記在前頭
···第70行–105行是對s_gets函數的解析···
···第32行–39行和93行–96行主要解釋了while語句的不同用法----前者是輔助scanf函數,後者是丢棄了第n-1個字元後的多餘輸入,但本質上是一樣的。
···c primer plus這本書多次調用這個自定義函數s_gets函數講解知識點,其中第11章和12、13章調用時,函數有細微的改變,但是93行–96行while語句的用法是一樣的·····
//* 程式清單14.2book.c -- 一本書的圖書目錄 */
#include <stdio.h>
#include <string.h>
#define MAXTITL 40
#define MAXAUTL 40
#define MAXBKS 100 //最多儲存100本書的資料
char *s_gets(char *st, int n);
struct book
{
char title[MAXTITL];
char auther[MAXAUTL];
float value;
};
int main()
{
struct book library[MAXBKS]; //把library聲明為一個book類型的數組
int count = 0;
int index;
char ch;
puts("PLease input the 1th book's title.");
puts("And empty line to quit.");
while (s_gets(library[count].title, MAXTITL) != NULL && count < MAXBKS && library[count].title[0] != '\0')
{
printf("Please enter the %dth book's auther.\n", count + 1);
s_gets(library[count].auther, MAXAUTL);
printf("Please enter the %dth book's value.\n", count + 1);
scanf("%f", &library[count].value);
count++;
/*fun scanf遇到空格字元或換行符qian就結束,不讀取這兩個字元*/
/*若輸入12.50[Enter]--傳送字元-->12.50\n */
/*下面兩行的意思是擷取下一個字元但不儲存:如不是'\n',則繼續擷取下一個字元但不儲存;
若是換行符,則表示此時本行輸入已經全部被擷取,可以再用s_get函數擷取下一組資訊*/
while (getchar() != '\n')
{
continue;
}
printf("PLease input the %d book's title.\n", count + 1);
}
printf("Ok,Now would you want to diplay the book list?\n");
puts("<A> Yes <B> No");
while ((ch = getchar()) != EOF)
{
if (ch == 'A')
{
for (index = 0; index < count; index++)
{
printf("%s by %s: $%.2f.\n", library[index].title, library[index].auther, library[index].value);
}
break;
}
else if (ch == 'B')
{
puts("Ok!Bye!");
break;
}
else
{
puts("Please check your input code and input again.");
}
}
printf("Done!");
return 0;
}
/*這裡主要解釋了27行while語句存在的意義*/
/*該函數從螢幕讀取n-1個字元,将其中的換行符替換為空字元,成功時傳回st,失敗時傳回NULL指針*/
char *s_gets(char *st, int n)
{
char *ret_val;
char *find;
/*fgets擷取的是一行字元串,遇到換行符或讀取到n-1個字元時結束讀取,前者将換行符儲存進字元串st,然後再儲存一個空字元*/
/*注意字元串中的空格字元不是'\0'*/
ret_val = fgets(st, n, stdin);
/*成功讀取資料為傳回str,不成功則傳回NULL空指針 */
if (ret_val != NULL)
{
/*str是專門搜尋字元串中的字元的,遇到'\0'或者找到目标字元就會停止*/
/*查找st所指向的字元串中的換行符'\n',傳回指向該字元的指針,未找到傳回NULL指針*/
find = strchr(st, '\n');
/*表示找到了換行符*/
if (find != NULL)
{
*find = '\0';
}
/*else表示未找到'\n',但是已經搜尋到了字元串末尾,這是因為fgets擷取了n-1個字元就結束了*/
else
{
/*此時fgets擷取了n-1個字元,螢幕中的輸入字元沒有讀完故使用getchar繼續讀取,當讀取到'\n'時表示該行輸入讀取完,
目的是為了避免,接下來繼續讀取字元時,續接之前的輸入資料,這實質上是丢棄了第n-1個字元後的多餘輸入,如果再次獲
取輸入字元要從下一行開始*/
/*getchar()函數是從标準輸入(螢幕)讀取下一個字元*/
while (getchar() != '\n')
{
continue;
}
}
}
return ret_val;
}