【开源中国 APP 全新上线】“动弹” 回归、集成大模型对话、畅读技术报告”
/* str_cat.c -- joins two strings */
#include <stdio.h>
#include <string.h> /* declares the strcat() function */
#define SIZE 80
char * s_gets(char * st, int n);
int main(void)
{
char flower[SIZE];
char addon[] = "s smell like old shoes.";
puts("What is your favorite flower?");
if (s_gets(flower, SIZE))
{
strcat(flower, addon);
puts(flower);
puts(addon);
}
else
puts("End of file encountered!");
puts("bye");
return 0;
}
char * s_gets(char * st, int n)
{
char * ret_val;
int i = 0;
ret_val = fgets(st, n, stdin);
if (ret_val)
{
while (st[i] != '\n' && st[i] != '\0')
i++;
if (st[i] == '\n')
st[i] = '\0';
else
while (getchar() != '\n')
continue;
}
return ret_val;
}
这个标红的地方,如果让我写,应该是while (st[i] != '\n') ,
请问为啥要写成getchar()!='\n' ???
getchar() 的用法是:“它从标准输入里读取下一个字符”,为什么用的这个地方?
ret_val = fgets(st, n, stdin); 这个函数的功能是:"从文件流读取一行,送到缓冲区"
表示已经在读取一行字符串了,为啥后面还要用while (getchar() != '\n') ???
当 fgets(st, n, stdin) 成功返回, 即 ret_val 不是 NULL 的时候, 有两种情况:
如果调用 fgets的次数多于1,那就有必要删除头一次的剩余数据,就是说。一定要使用 while (getchar() != '\n') continue; 循环体,以删除这些残留在缓冲中的"垃圾",防止这些"垃圾"破坏下一次的输入处理。不过,楼主的程序,仅调用 fgets 一次,所以,不写循环体代码: while (getchar() != '\n') continue; , 即不删除'垃圾', 也无妨。
测试 while (getchar() != '\n') continue; 的功能。
所用程序:
数据:月季Everflowering_Rose,牡丹peony, 和 玫瑰rose
依次将这3个不同中英文字符串数据输入。
中文(每个字符占2个字节)在前, 英文(每个字符占1个字节)在后, 没有空格。
读入的最大字符数量 (包括 '\n'), 是 10 ( #define SIZE 10)
场景 Case 1:使用 while (getchar() != '\n') continue; 循环体
由输出结果看出,只能成功地读入前9个字节 (因为 SIZE 是 10) ,剩余数据均被抛弃。
第一次只显示 "月季Everf" (9个字节)
第二次圆满显示 "牡丹peony",因为它刚好占9个字节。
第三次圆满显示 "玫瑰rose",因为它只仅占8个字节。
输出:
场景 Case 2:不使用 while (getchar() != '\n') continue; 循环体
由输出结果可见,上次残留在缓存里的数据,继续充当下一次的数据,致使结果不可理喻。
输出:
有同感。
while(getchar()!='\n') continue; 的作用,是"吃掉"用户键入一行字符串之后无意滋生出的无用的符号。不过,将它套在 过滤 已经获得的缓冲区字符串 的 while 循环语句 “while (st[i] != '\n' && st[i] != '\0')" 之内,我也不解。多此一举。我看,应当删除这段代码
题外讨论:程序回应的英文语句,是否可以稍加修改成:
char addon[] = "'s smell looks a bit like old shoes.";
想想调用fgets()缓冲区满的情况
有没有其他朋友解释下嘛
请大家帮忙再分析下哦,谢谢
引用来自“4F5DA2”的评论
想想调用fgets()缓冲区满的情况
我感觉我明白了,我这边的代码其SIZE=80,我待会可以测试下,我把SIZE 改成8,我输入10个字符,理论上只会使用前8位.
ret_val = fgets(st, n, stdin); 只会读取前8位,此时没有发现'\0'和'\n',剩下的两位字符需要while (getchar() != '\n') 去吃掉
我是这样理解的,不知道对不对.
我是受到下面的描述启发的.