c语言getchar的用法
许多初学者都习惯用 char 型变量接收 getchar、getc,fgetc 等函数的返回值,其实这么做是不对的,并且隐含着足以致命的错误。getchar()最典型的程序也就几行代码而已。下面我们来看看c语言getchar的用法。一、getchar的两点总结:
1.getchar是以行为单位进行存取的。
当用getchar进行输入时,如果输入的第一个字符为有效字符(即输入是文件结束符EOF,Windows下为组合键Ctrl+Z, Unix/Linux下为组合键Ctrl+D),那么只有当最后一个输入字符为换行符'\n'(也可以是文件结束符EOF,EOF将在后面讨论)时, getchar才会停止执行,整个程序将会往下执行。譬如下面程序段:
while((c = getchar()) != EOF){
putchar(c);
}
执行程序,输入:abc,然后回车。则程序就会去执行puchar(c),然后输出abc,这个地方不要忘了,系统输出的还有一个回车。然后可以继续输入,再次遇到换行符的时候,程序又会把那一行的输入的字符输出在终端上。
对于getchar,肯定很多初学的朋友会问,getchar不是以字符为单位读取的吗?那么,既然我输入了第一个字符a,肯定满足while循环(c = getchar()) != EOF的条件阿,那么应该执行putchar(c)在终端输出一个字符a。不错,我在用getchar的时候也是一直这么想的,但是程序就偏偏不着样执 行,而是必需读到一个换行符或者文件结束符EOF才进行一次输出。
对这个问题的一个解释是,在大师编写C的时候,当时并没有所谓终端输入的概念,所有的输入实际上都是按照文件进行读取的,文件中一般都是以行为单位的。因 此,只有遇到换行符,那么程序会认为输入结束,然后采取执行程序的其他部分。同时,输入是按照文件的方式存取的,那么要结束一个文件的输入就需用到EOF (Enf Of File). 这也就是为什么getchar结束输入退出时要用EOF的原因。
2.getchar()的返回值一般情况下是字符,但也可能是负值,即返回EOF。
这里要强调的一点就是,getchar函数通常返回终端所输入的字符,这些字符系统中对应的ASCII值都是非负的。因此,很多时候,我们会写这样的两行代码:
char c;
c = getchar();
这样就很有可能出现问题。因为getchar函数除了返回终端输入的字符外,在遇到Ctrl+D(Linux下)即文件结束符EOF时,getchar ()的返回EOF,这个EOF在函数库里一般定义为-1。因此,在这种情况下,getchar函数返回一个负值,把一个负值赋给一个char型的变量是不 正确的。为了能够让所定义的变量能够包含getchar函数返回的所有可能的值,正确的定义方法如下(K&R C中特别提到了这个问题):
int c;
c = getchar();
二、EOF的两点总结(主要指普通终端中的EOF)
1.EOF作为文件结束符时的情况:
EOF虽然是文件结束符,但并不是在任何情况下输入Ctrl+D(Windows下Ctrl+Z)都能够实现文件结束的功能,只有在下列的条件下,才作为文件结束符。
(1)遇到getcahr函数执行时,要输入第一个字符时就直接输入Ctrl+D,就可以跳出getchar(),去执行程序的其他部分;
(2)在前面输入的字符为换行符时,接着输入Ctrl+D;
(3)在前面有字符输入且不为换行符时,要连着输入两次Ctrl+D,这时第二次输入的Ctrl+D起到文件结束符的功能,至于第一次的Ctrl+D的作用将在下面介绍。
其实,这三种情况都可以总结为只有在getchar()提示新的一次输入时,直接输入Ctrl+D才相当于文件结束符。
2.EOF作为行结束符时的情况,这时候输入Ctrl+D并不能结束getchar(),而只能引发getchar()提示下一轮的输入。
这种情况主要是在进行getchar()新的一行输入时,当输入了若干字符(不能包含换行符)之后,直接输入Ctrl+D,此时的Ctrl+D并不是文件 结束符,而只是相当于换行符的功能,即结束当前的输入。以上面的代码段为例,如果执行时输入abc,然后Ctrl+D,程序输出结果为:
abcabc
注意:第一组abc为从终端输入的,然后输入Ctrl+D,就输出第二组abc,同时光标停在第二组字符的c后面,然后可以进行新一次的输入。这时如果再次输入Ctrl+D,则起到了文件结束符的作用,结束getchar()。
如果输入abc之后,然后回车,输入换行符的话,则终端显示为:
abc //第一行,带回车
abc //第二行
//第三行
其中第一行为终端输入,第二行为终端输出,光标停在了第三行处,等待新一次的终端输入。
从这里也可以看出Ctrl+D和换行符分别作为行结束符时,输出的不同结果。
EOF的作用也可以总结为:当终端有字符输入时,Ctrl+D产生的EOF相当于结束本行的输入,将引起getchar()新一轮的输入;当终端没有字符 输入或者可以说当getchar()读取新的一次输入时,输入Ctrl+D,此时产生的EOF相当于文件结束符,程序将结束getchar()的执行。
【补充】本文第二部分中关于EOF的总结部分,适用于终端驱动处于一次一行的模式下。也就是虽然getchar()和putchar()确实是按照每次一个字符 进行的。但是终端驱动处于一次一行的模式,它的输入只有到“\n”或者EOF时才结束,因此,终端上得到的输出也都是按行的。
如果要实现终端在读一个字符就结束输入的话,下面的程序是一种实现的方法(参考《C专家编程》,略有改动)
复制代码 代码如下:
/*Edit by Godbach
CU Blog: http://blog.chinaunix.net/u/33048/
*/
#include <stdio.h>
#include <stdlib.h>
int
main(void)
{
int c;
/* 终端驱动处于普通的一次一行模式 */
system("stty raw");
/* 现在的终端驱动处于一次一个字符模式 */
c = getchar();
putchar();
/* 终端驱动处又回到一次一行模式 */
system("stty cooked");
return 0;
}
编译运行该程序,则当如入一个字符时,直接出处一个字符,然后程序结束。
由此可见,由于终端驱动的模式不同,造成了getchar()输入结束的条件不一样。普通模式下需要回车或者EOF,而在一次一个字符的模式下,则输入一个字符之后就结束了。
绛旓細getchar鏄C璇█涓殑涓涓爣鍑嗗簱鍑芥暟锛屽畠鐨勪綔鐢ㄦ槸鑾峰彇杈撳叆缂撳啿鍖轰腑鐨勪竴涓瓧绗﹀苟杩斿洖锛屽父鐢ㄤ簬璇诲彇鏉ヨ嚜閿洏鐨勮緭鍏ャ傝鍑芥暟鍦ㄥ鐞嗚緭鍏ユ椂寰堟湁鐢ㄥ锛屽彲浠ョ敤鏉ュ疄鐜版帶鍒跺彴浜や簰寮忚緭鍏ョ殑鎿嶄綔銆備娇鐢╣etchar璇诲彇鐢ㄦ埛鐨勮緭鍏ユ椂锛岄渶瑕佹敞鎰忚緭鍏ユ祦涓彲鑳戒細閬楃暀鍥炶溅绗︺佹崲琛岀浠ュ強绌烘牸绛夌壒娈婂瓧绗︼紝涓轰簡鑳藉姝g‘澶勭悊杩欎簺杈撳叆锛...
绛旓細getchar()鏄C璇█涓殑涓涓緭鍏ュ嚱鏁 getchar()鏄疌璇█涓殑涓涓緭鍏ュ嚱鏁帮紝鍙互浠庢爣鍑嗚緭鍏ユ祦锛堥氬父鏄敭鐩橈級涓幏鍙栧瓧绗︺傚畠鍦ㄧ▼搴忎腑闈炲父甯哥敤锛屽彲浠ュ府鍔╂垜浠幏鍙栫敤鎴疯緭鍏ュ拰澶勭悊鏁版嵁銆備娇鐢╣etchar()鍑芥暟鏃讹紝鎴戜滑鍙渶瑕佸湪绋嬪簭涓皟鐢ㄥ畠锛屽綋鐢ㄦ埛閿叆瀛楃骞舵寜涓嬪洖杞﹂敭鍚庯紝璇ュ嚱鏁颁細杩斿洖閿叆鐨勫瓧绗︼紝骞跺皢瀹冨瓨鍌ㄥ埌...
绛旓細`getchar`鏄竴涓湪C璇█涓父鐢ㄧ殑鍑芥暟锛屽畠浠庢爣鍑嗚緭鍏ワ紙閫氬父鏄敭鐩橈級璇诲彇涓涓瓧绗︼紝骞惰繑鍥炲畠銆傛崲鍙ヨ瘽璇达紝瀹冩槸涓涓粠鐢ㄦ埛閭i噷鑾峰彇杈撳叆鐨勫嚱鏁般傛瘡娆¤皟鐢╜getchar`鏃讹紝绋嬪簭浼氱瓑寰呯敤鎴疯緭鍏ヤ竴涓瓧绗︼紝鐒跺悗杩斿洖璇ュ瓧绗︺備娇鐢getchar鐨渚嬪瓙 ```c #include int main() { char c; printf("璇疯緭鍏ヤ竴涓瓧绗: ...
绛旓細褰撲綘鍦ㄩ敭鐩樹笂杈撳叆涓涓瓧绗﹀悗鎸夊洖杞;(杈撳叆u)閭d箞瀛楃鍙橀噺a鐨勫煎氨鏄'u'浜.main() { char c; c=getchar(); /*浠庨敭鐩樻帴鏀朵竴涓瓧绗︼紝鍙兘涓涓紝澶氫簬涓涓叾浣欎綔搴*/ putchar(c); } 杩樺彲浠ヨ繖鏍风敤锛 main() { putchar(getchar()); } C璇█鏄竴闂ㄩ氱敤璁$畻鏈虹紪绋嬭瑷锛屽簲鐢ㄥ箍娉涖C璇█鐨璁捐...
绛旓細c璇█閲getchar锛堬級鏄粈涔 getchar鍑藉紡浠庢爣鍑嗚緭鍏ラ噷璇诲彇涓嬩竴涓瓧鍏冿紝杩斿洖鍨嬪埆涓篿nt鍨嬶紝杩斿洖鍊间负浣跨敤鑰呰緭鍏ョ殑ASC鈪$爜锛屽嚭閿欒繑鍥濫OF銆 璇ュ嚱寮忓鍛婂湪stdio.h鏍囧ご妗f涓紝浣跨敤鐨勬椂鍊欒鍖呭惈stdio.h鏍囧ご妗f銆傞氬父锛屽彲浠ュ埄鐢╣etchar鍑藉紡璁╃▼寮忛櫎閿欐墽琛岀粨鏉熷悗绛夊緟绋嬪紡璁捐鑰呮寜涓嬮敭鐩樻墠杩斿洖缂栬緫浠嬮潰銆C璇█...
绛旓細鑲畾婊¤冻while寰幆(c = getchar()) != EOF鐨勬潯浠堕樋锛岄偅涔堝簲璇ユ墽琛宲utchar(c)鍦ㄧ粓绔緭鍑轰竴涓瓧绗銆備笉閿欙紝鎴戝湪鐢getchar鐨鏃跺欎篃鏄竴鐩磋繖涔堟兂鐨勶紝浣嗘槸绋嬪簭灏卞亸鍋忎笉鐫鏍锋墽琛岋紝鑰屾槸蹇呴渶璇诲埌涓涓崲琛岀鎴栬呮枃浠剁粨鏉熺EOF鎵嶈繘琛屼竴娆¤緭鍑恒2.getchar()鐨勮繑鍥炲间竴鑸儏鍐典笅鏄瓧绗︼紝浣嗕篃鍙兘鏄礋鍊硷紝鍗宠繑鍥...
绛旓細int getchar(void)锛2锛夊弬鏁 NA 锛3锛夊姛鑳 C 搴撳嚱鏁癷nt getchar(void)浠庢爣鍑嗚緭鍏 stdin 鑾峰彇涓涓瓧绗︼紙涓涓棤绗﹀彿瀛楃锛夈傝繖绛夊悓浜getc甯︽湁 stdin 浣滀负鍙傛暟銆傦紙4锛夎繑鍥炲 璇ュ嚱鏁颁互鏃犵鍙 char 寮哄埗杞崲涓 int 鐨勫舰寮忚繑鍥炶鍙栫殑瀛楃锛屽鏋滃埌杈炬枃浠舵湯灏炬垨鍙戠敓璇婚敊璇紝鍒欒繑鍥 EOF銆傦紙5锛鐢ㄦ硶 璇ュ嚱鏁...
绛旓細鍏蜂綋鐢ㄦ硶锛岃繖閲岄渶瑕佸厛鏂板缓涓涓C璇█鐨勭┖鏂囦欢锛岄殢鍚庤緭鍏ユ紨绀轰唬鐮侊細2銆佺▼搴忔槸绠鍗曠殑getchar()鐢ㄦ硶锛岃繖閲岃緭鍏ヤ竴涓瓧绗︼紝绋嬪簭浼氬垽鏂槸鍚︿负瀛楃锛屽鏋滀笉鏄垯杈撳嚭閿欒锛屾槸杈撳嚭瀛楃锛3銆佽繍琛岀▼搴忥紝杈撳叆浠绘剰涓涓瓧绗︼紝杩欓噷杈撳叆瀛楃a锛屾寜涓嬪洖杞︾▼搴忎細鑷姩鍒ゆ柇a鏄竴涓瓧绗︼紝浠ヤ笂灏辨槸getchar鍑芥暟鐨勭敤娉锛...
绛旓細鍥炶溅鍓嶇殑鎵鏈夎緭鍏ュ瓧绗﹂兘浼氶愪釜鏄剧ず鍦ㄥ睆骞曚笂锛屼絾鍙湁绗竴涓瓧绗︿綔涓哄嚱鏁扮殑杩斿洖鍊笺浣跨敤鏂规硶锛1銆佽緭鍏ュ涓嬪懡浠わ紝瀹氫箟瀛楃銆2銆佷娇鐢getchar鍑芥暟鑾峰緱杈撳叆瀛楃銆3銆佷娇鐢╬utchar鍑芥暟灏嗗彉閲忚緭鍑恒4銆佺偣鍑荤紪璇戞寜閽紝瀵圭▼搴忚繘琛岀紪璇戙5銆佹彁绀烘棤閿欒鏃讹紝杩涜绋嬪簭杩愯銆6銆佸脊鍑虹殑鐣岄潰杈撳叆瀛楃銆7銆佽繍琛岀晫闈㈠涓嬨
绛旓細鍦C璇█涓紝getchar鍑芥暟鏄瓧绗﹁緭鍏ュ嚱鏁帮紝putchar浠h〃鏄崟涓瓧绗﹁緭鍑哄嚱鏁般1銆乬etchar()鍑芥暟鐨勭敤娉锛歝har a=getchar()銆備綔鐢ㄦ槸浠庤绠楁満缁堢锛堜竴鑸负閿洏锛夎緭鍏ヤ竴涓瓧绗︺俫etchar()鍑芥暟鍙兘鎺ユ敹涓涓瓧绗︼紝鍏跺嚱鏁板煎氨鏄粠杈撳叆璁惧寰楀埌鐨勫瓧绗︺2銆乸utchar()鍑芥暟鐨勭敤娉: int putchar(int ch)銆備綔鐢ㄦ槸鍚...