记在前头
···第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;
}