scanf可以识别字符串中的格式字符吗?

时间:2009-07-12 19:56:54

标签: c string scanf

假设我希望标准输入中的项目列表是分开的购买逗号,如下所示:

 item1, item2, item3,...,itemn

我还想允许用户在项目和逗号之间发出空格,所以这种输入在我的程序中是合法的:

item1,item2,item3,...,itemn

如果我像这样使用scanf

scanf("%s,%s,%s,%s,...,%s", s1, s2, s3, s4,...,sn);

当没有空格(我测试过它)时会失败,因为它会将整个输入称为一个字符串。那么如何才能用C标准库函数解决这个问题?

3 个答案:

答案 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”等字符串。