1. 程式人生 > >C語言實戰105例--1一個價值三天的BUG

C語言實戰105例--1一個價值三天的BUG

本系列筆記是參考《C語言實戰105例》及程式碼的學習筆記。

本節是使用sscanf函式處理行定向的輸入。程式為實現輸入兩個整數求和的功能。

注意:1、指標引數的型別必須是對應格式的程式碼的正確型別

           2、正確使用限定符(指定引數的長度)

程式碼如下:

#include<stdio.h>
#include<stdlib.h>
#define BUFFERSIZE 1024  /*允許處理的最長行有1024個字元*/
int main()
{
	int a,b,sum;         /*將輸入的兩個數分別儲存在變數a和b中,sum=a+b*/
	char buffer[BUFFERSIZE];
	printf("***********************************\n");
	printf("*  Welcome to use our counter     *\n");
	printf("*  Input two integers in one line *\n");
	printf("*  The sum will be printed        *\n");
	printf("*  Input the char '#' to quit     *\n");
	printf("***********************************\n");
	/*從標準輸入(stdin)讀取輸入的資料,儲存在buffer中.
	如果讀取的第一個字元是'#'則推出程式*/
	while((fgets(buffer,BUFFERSIZE,stdin)!=NULL)&&(buffer[0]!='#'))
	{
		if(sscanf(buffer,"%d %d",&a,&b)!=2)              /*處理儲存在buffer中的一行資料*/
			{
				printf("The input is skipped:%s",buffer);/*如果輸入的數字不是兩個則報錯*/
				continue;                               /*繼續讀取下一組資料*/			
			}
		sum=a+b;                                         /*計算a與b的和*/
		printf("The sum of %d and %d is %d\n",a,b,sum);  /*輸出計算結果*/
	}
	return 0;
}

其中我不懂的地方:

1、buffer--它一般用來定義陣列,因為它本身的意思就是“緩衝區”,在C語言裡,陣列就是個緩衝區,所以用常常用它。

2、fgets函式

  • 函式原型是:char *fgets(char *s, int n, FILE *stream);

       從檔案結構體指標stream中讀取資料,每次讀取一行。讀取的資料儲存在buf指向的字元陣列中,每次最多讀取bufsize-1個字元(第bufsize個字元賦'\0'),如果檔案中的該行,不足bufsize-1個字元,則讀完該行就結束。

       如若該行(包括最後一個換行符)的字元數超過bufsize-1,則fgets只返回一個不完整的行,但是,緩衝區總是以

NULL字元結尾,對fgets的下一次呼叫會繼續讀該行。

       函式成功將返回buf,失敗或讀到檔案結尾返回NULL。因此我們不能直接通過fgets的返回值來判斷函式是否是出錯而終止的,應該藉助feof函式或者ferror函式來判斷。

  • 與gets相比使用這個好處是:讀取指定大小的資料,避免gets函式從stdin接收字串而不檢查它所複製的快取的容積導致的快取溢位問題。
  • 功能:

       1、《UNIX 環境高階程式設計》中指出,每次呼叫fgets函式會造成標準輸出裝置自動刷清!案例詳見《UNIX環境高階程式設計(第二版)》中程式清單1-5和課後習題5.7,習題5.7的答案中給出了相關的論述。

       2、初入門者,大多數是在WINDOWS下,使用VS進行練習的。此環境下,對注意1中的情況進行測試,並不能看到案例中所描述的情景,因為具體的實現不同。

       stream檔案流指標體指向檔案內容地址的偏移原則

       例:

              如果一個檔案的當前位置的文字如下

              Love, I Have

              Since you can do it.

              如果用fgets(str1,6,file1);去讀取

              則執行後str1 = "Love," ,讀取了6-1=5個字元

              這個時候再執行fgets(str1,20,file1)則執行後str1 = " I Have\n"

              而如果

              fgets(str1,23,file1);

              則執行str1="Love ,I Have",讀取了一行(包括行尾的'\n',並自動加上字串結束符'\0'),當前檔案位置移至下一行,雖       然23大於當前行上字元總和,可是不會繼續到下一行。而下一次呼叫fgets()繼續讀取的時候是從下一行開始讀。