posts - 134,comments - 22,trackbacks - 0

          首先,這兩個(gè)函數(shù)不是C標(biāo)準(zhǔn)庫(kù)中的函數(shù),

          int getch(void)    //從標(biāo)準(zhǔn)輸入讀入一個(gè)字符,當(dāng)你用鍵盤輸入的時(shí)候,屏幕不顯示你所輸入的字符。也就是,不帶回顯。
          int getche(void)    //從標(biāo)準(zhǔn)輸入讀入一個(gè)字符,鍵盤輸入的時(shí)候,屏幕顯示所輸入的字符。帶回顯。

          這兩個(gè)函數(shù)包含在頭文件conio.h中,需要記住的是conio.h不是C標(biāo)準(zhǔn)庫(kù)中的頭文件。Micorsoft 和 Borland的 C編譯器提供了conio.h,用來(lái)創(chuàng)建控制臺(tái)文本用戶界面。一般在Windows系統(tǒng)下安裝了VS、VC等,就可以包含conio.h頭文件。但是一般 在Unix、Linux系統(tǒng)中,/usr/include/中都沒有這個(gè)頭文件。

          getch和getche在等待用戶從鍵盤輸入的時(shí)候,用戶按下一個(gè)鍵后,不需要按回車,程序自動(dòng)往下執(zhí)行。在Linux中,終端輸入在缺省情況下是被“一鍋端”的,也就是說整行輸入是被一起處理的。通常,這是一種人們所希望的方便的辦法,但它也意味著在讀入數(shù)據(jù)時(shí)必須按一下回車鍵表示輸入行結(jié)束后才能得到輸入的數(shù)據(jù)。在游戲中,很多都提供了“老板鍵”,它的實(shí)現(xiàn),就是利用了這兩個(gè)函數(shù)。

           

          其次,除了getch和getche,其他的都是C標(biāo)準(zhǔn)庫(kù)中的頭文件,包含在頭文件stdio.h中。

          
          
          int fgetc ( FILE * stream ); //從流stream中讀一個(gè)字符??梢詫?biāo)準(zhǔn)輸入stdin作為它的實(shí)參,這時(shí)候從標(biāo)準(zhǔn)輸入讀取一個(gè)字符。
          int getc(FILE * stream);     //和fgetc等效,由fgetc通過宏實(shí)現(xiàn)。
          int getchar ( void );     //從標(biāo)準(zhǔn)輸入stdin讀入一個(gè)字符,程序等待你輸入的時(shí)候,你可以輸入多個(gè)字符,回車后程序繼續(xù)執(zhí)行。
                                           //但getchar只讀入一個(gè)字符
          說明:getc、getchar都是通過宏定義借助fgetc實(shí)現(xiàn)。如getchar的實(shí)現(xiàn)為,#define getchar() fgetc(stdin)。
           
          char * fgets (char * str, int num, FILE *stream);
                           //從流stream中讀入最多num個(gè)字符到字符數(shù)組str中,當(dāng)遇到換行符時(shí)、或讀到num-1個(gè)字符時(shí)停止。
                           //自動(dòng)加上'\0'空字符結(jié)尾
          char * gets ( char * str ); //從標(biāo)準(zhǔn)輸入stdin讀取一個(gè)字符串,遇到換行或結(jié)束時(shí)候終止。
                           //不同于fgets,他沒有指定num,所以需要注意字符數(shù)組str的大小。
           
          說明: fgets和gets之間沒有宏定義的關(guān)系,彼此各自有自己的實(shí)現(xiàn)。蠕蟲病毒的實(shí)現(xiàn)就是函數(shù)gets的“功勞”。gets函數(shù)的任務(wù)是從流中讀入一個(gè)字符串。它的調(diào)用者會(huì)告訴它把讀入的字符串放在什么地方。但是,gets()函數(shù)并不檢查緩沖區(qū)大小,如果調(diào)用者提供了一個(gè)指向堆棧的指針,并且get()函數(shù)讀入的字符數(shù)量超過了超過了緩沖區(qū)的空間大小,get()會(huì)愉快地將多出來(lái)的字符繼續(xù)寫入到堆棧中,這就覆蓋了堆棧中原來(lái)的內(nèi)容。如:
          main()
          {
             
          char line[512];    //在程序的堆棧上分配512個(gè)字符的空間
             ...
             gets(line);        
          //蠕蟲病毒的入口,可以將惡意代碼通過多出來(lái)的數(shù)據(jù)寫入堆棧
          }

           

          建議不要用getch和getche,因?yàn)樗鼈儾皇荂標(biāo)準(zhǔn)庫(kù)中的函數(shù)。用它們寫出的程序可移植性差,不同的編譯器不保證可以包含conio.h。建議用fgets函數(shù)徹底替代gets函數(shù)。

           

          另外,絕大多數(shù)的這些get函數(shù),都有對(duì)應(yīng)的put版本。

          int fputc ( int character, FILE * stream );

          int putc ( int character, FILE * stream );       //通過宏定義和fputc實(shí)現(xiàn)

          int putchar ( int character );        //通過宏定義實(shí)現(xiàn):#define putchar(c) fputc(c, stdout)

           

          int fputs ( const char * str, FILE * stream );

          int puts ( const char * str );

          說明:兩者之間無(wú)宏定義實(shí)現(xiàn)關(guān)系。puts(const char *str)近似等效于fputs(cosnt char *str, stdout),不同點(diǎn)是前者還輸出一個(gè)'\n'

           

          最后,關(guān)于EOF

          EOF是在stdio.h文件中定義的符號(hào)常量,值為-1。如,

          fputc函數(shù)返回一個(gè)值:如果輸出成功則返回值就是輸出的字符;如果輸出失敗,則返回一個(gè)EOF。 

          fgetc函數(shù)讀字符時(shí)遇到文件結(jié)束符,函數(shù)返回一個(gè)文件結(jié)束標(biāo)記EOF。如果想從一個(gè)磁盤文件順序讀入字符并在屏幕上顯示,可以:

          ch = fgetc(fp);
          while(ch != EOF){
            putchar(ch);
            ch 
          = fgetc(fp);
          }

           

          注意,EOF不是可輸出字符,因此不能在屏幕上顯示。由于ASCII碼不可能出現(xiàn)-1,因此EOF定義為-1是合適的。當(dāng)讀入的字符值等于-1(即 EOF)時(shí),表示讀入的已不是正常的字符,而是文件結(jié)束符。但以上只適用于讀取文本文件的情況?,F(xiàn)在ANSI C 已經(jīng)允許用緩沖文件系統(tǒng)處理二進(jìn)制文件,而讀入某一個(gè)字節(jié)中的二進(jìn)制數(shù)據(jù)的值有可能是-1,而這又恰好是EOF的值。這就出現(xiàn)了需要讀入有用數(shù)據(jù),卻處理 為“文件結(jié)束”。feof(fp) 用來(lái)測(cè)試fp所指向的文件當(dāng)前狀態(tài)是否是“文件結(jié)束”。如果想順序讀入一個(gè)二進(jìn)制文件數(shù)據(jù),可以:

          while(!feof(fp)){
             c 
          = fgetc(fp);
             ...

          posted on 2010-07-26 17:34 何克勤 閱讀(421) 評(píng)論(0)  編輯  收藏 所屬分類: C/C++
          主站蜘蛛池模板: 广宁县| 共和县| 广德县| 昌吉市| 卢龙县| 巴楚县| 乐安县| 河西区| 华容县| 定结县| 阜城县| 济南市| 恩平市| 麻江县| 永靖县| 偏关县| 晋州市| 铜山县| 公安县| 平原县| 桐城市| 克东县| 洪泽县| 岫岩| 台北市| 定日县| 遂昌县| 高淳县| 比如县| 湖南省| 琼中| 莲花县| 会宁县| 永顺县| 清苑县| 清丰县| 中宁县| 长海县| 虞城县| 惠州市| 竹溪县|