假设我希望标准输入中的项目列表是分开的购买逗号,如下所示:
item1, item2, item3,...,itemn
我还想允许用户在项目和逗号之间发出空格,所以这种输入在我的程序中是合法的:
item1,item2,item3,...,itemn
如果我像这样使用scanf
:
scanf("%s,%s,%s,%s,...,%s", s1, s2, s3, s4,...,sn);
当没有空格(我测试过它)时会失败,因为它会将整个输入称为一个字符串。那么如何才能用C标准库函数解决这个问题?
答案 0 :(得分:8)
快速回答永远不会使用scanf来读取用户输入。它用于从文件中读取严格格式化的输入,即使这样也不是很好。至少,您应该读取整行,然后使用sscanf()解析它们,这样您就有机会纠正错误。最好你应该编写自己的解析函数
如果您实际使用的是C ++,请研究使用c ++字符串和流类,这些类更强大,更安全。
答案 1 :(得分:7)
您可以查看strtok
。首先将该行读入缓冲区,然后进行标记化:
const int BUFFERSIZE = 32768;
char buffer[BUFFERSIZE];
fgets(buffer, sizeof(buffer), stdin);
const char* delimiters = " ,\n";
char* p = strtok(buffer, delimiters);
while (p != NULL)
{
printf("%s\n", pch);
p = strtok(NULL, delimiters);
}
但是,对于strtok
,您需要了解potential issues related to reentrance。
答案 2 :(得分:2)
我想最好为此编写自己的解析函数。但是如果你仍然喜欢scanf,尽管存在陷阱,你可以做一些解决方法,只需用%[^,\ t \ r \ n]替换%s。
%s匹配非空白字符序列的问题,所以它也吞下逗号。因此,如果用%[^,\ t \ r \ n \ n]替换%s,它将几乎相同(不同之处在于%s使用isspace(3)来匹配空格字符,但在这种情况下,您明确指定了哪些空格字符匹配和此列表可能与isspace不同。
请注意,如果您想在逗号之前和之后允许空格,则必须在格式字符串中添加空格。格式字符串“%[^,\ t \ r \ n],%[^,\ t \ r \ n]”匹配“hello,world”,“hello,world”,“hello,world”等字符串。