我创建了一个简单的结构:
struct album {
char title[20];
char artist[20];
};
以后在程序中我创建了一个实例a
(struct album a;
)。我只需要让用户输入标题和艺术家,以便将它们保存在适当的位置然后打印值:
printf("Please enter your album: \n");
printf("album name: ");
scanf("%.20s", a.title);
fflush(stdin);
printf("artist: ");
scanf("%.20s", a.artist);
printf("======\n");
printf("The album's name is %s and the artist is %s\n", a.title, a.artist);
然而,当我运行这个时,我得到了这个结果:
部分输入文字丢失。究竟出了什么问题?
答案 0 :(得分:4)
scanf读取字符到空白区域。因此,如果你要进入米歇尔·杰克逊,米歇尔和杰克逊之间的空间会终止你的弦乐,所以你只能得到字符串米歇尔。
尝试使用fgets:
之类的东西fgets(a.artist, 20, stdin);
fgets获取终止新行上的字符串而不是空格。
**如果您确实使用fgets,请确保从字符串末尾删除新行字符,最后不要使用新行字符。
答案 1 :(得分:2)
使用scanf中的%s
说明符,长度说明符是要写入的字符数。这与大多数期望整个缓冲区大小的函数不同。
由于缓冲区需要包含空终止符,因此您需要在此处使用"%.19s"
。另一个选择是不对该值进行硬编码:
scanf("%.*s", (int)sizeof a.title - 1, a.title);
请注意,这仅在a.title
是数组(不是指针)时才有效,并且必须使用强制转换,因为int
可能比size_t
小,但*
期待int
。
正如其他人所指出的那样,%s
用于读取直到下一个空格。您可以阅读%[
的下一行,例如:
scanf("%.19[^\n]", a.title);
^
意味着在点击以下任何字符之前继续阅读,而\n
实际上是指新行,而不是一般的空格。
执行此操作后,您将需要刷新缓冲区,因为换行符仍将在缓冲区中。但是fflush(stdin);
不可移植。丢弃当前行其余部分的便携方式是:
int ch; while( (ch = getchar()) != EOF && ch != '\n' ) { }