我试图编写一个程序,该程序要从用户(控制台)开始一行,直到遇到逗号,句号或换行符,并告诉按照特定模式读取了多少个字符。
正确读取字符串,但计数不正确。
#include <stdio.h>
int main()
{
int n;
char s[100];
// The following line should read a string until (. or , or new-line in encountered)
// and %n should tell me the no of characters it read until that point
scanf("%[^.,\n]s%n", s, &n);
// The String in okay
printf("%s\n", s);
// But count of characters read is 0
printf("%d\n",n);
return 0;
}
"s"
中的"%[^.,\n]s%n"
停止扫描,因为在's'
之后无法读取%[^.,\n]
。 %[^.,\n]
应该已全部读入's'
。因此,以后的"%n"
永远不会出现,后来打印的n
,即0
是错误的代码-打印未初始化的n
-可能是任何int
或陷阱。扫描没有宽度限制。第99个字符后发生坏事。
使用scanf("%[^.,\n]s%n", s, &n);
,如果第一个字符是s
,则扫描将不会在.,\n
中保存任何内容。 s
的后续打印不好,因为s[]
未初始化。
代码无法检查scanf()
的返回值。
scanf()
不一定会按照“编写需要用户输入一行的程序”的指示来读取
line-使用scanf()
会使其停止运行。C Std Lib定义了以下一行,因此代码应尝试读取整行。
文本流是由行组成的有序字符序列,每行由零个或多个字符加上一个终止换行符组成。
scanf()
替代int n = 0; char s[100]; s[0] = '\0'; int cnt == scanf("%99[^.,\n]%n", s, &n); if (cnt == EOF) puts("Nothing was read"); else printf("%s\n", s);
更好的选择注意:超过100行的行需要附加代码。
我建议使用fgets()
而不是scanf()
:从用户那里接一行。
char s[100]; if (fgets(s, sizeof s, stdin)) { size_t n = strcspn(s, ".,\n"); // offset of string that does not have .,\n s[n] = '\0'; printf("%s\n", s); printf("%zu\n", n); }