用分隔符读取输入fscanf" _"

时间:2017-12-14 16:49:46

标签: c

如何在txt文件中扫描以下内容?

number_name_name1_number2

例如:

12_whoever_alternative with spaces_31

我试过了:

fscanf(f, "%d %[^_]_ %s %[^_]_ %s %[^_]_ %d", &number, name, name1, &number2)

3 个答案:

答案 0 :(得分:2)

首先,正如代码目前所示,您有undefined behavior

引用C11,章节§7.21.6.2

  

如果格式的参数不足,   行为未定义。

正如我们所见,在您的情况下,

fscanf(f, "%d %[^_]_ %s %[^_]_ %s %[^_]_ %d", &number, name, name1, &number2)
         |=================================|   |=============================|
               7 conversion specifiers                only 4 arguments!!!
                 in the format sting

请注意,[]对实际上形成了转换说明符,并且需要相应的参数才能保存扫描结果。

<强>建议:

也就是说,您可能希望使用fgets()来读取数据,并使用strtok()来标记输入以获取单个令牌。

答案 1 :(得分:1)

您目前拥有的是什么:

fscanf(f, "%d %[^_]_ %s %[^_]_ %s %[^_]_ %d", &number, name, name1, &number2)

匹配一个数字后跟一个空格,然后是一系列不包含下划线的字符,然后是下划线和空格等......所以完全没有你想要的那样。另外,每个%...都会期望相应的变量将值存储在。

要获得您想要的内容,您需要以下内容。

fscanf(f, "%d_%[^_]_%[^_]_%d", &number, name, name1, &number2);

并且不要忘记检查它返回的值 - 任何小于4的值意味着它没有找到所有4个值。

答案 2 :(得分:1)

如果你必须使用fscanf(),那么这种格式应该这样做:

fscanf(f, "%d_%[^_]_%[^_]_%d", &number, name, name1, &number2);

这假定分隔符是单个下划线,并且它不允许两个字符串为空。它 在每个数字之前容纳前导空格(将被忽略),并且允许两个字符串跨越行。虽然在数字需要使用%[指令而非%d之前拒绝空格,因此可以解决这两个潜在问题,因此扫描到字符串中。

总的来说,这可能比它的价值要大得多。编写自己的解析函数比依靠scanf()函数处理除最简单的格式之外的任何函数要好得多。