gpt4 book ai didi

c - 使用 C 使用 fscanf() 解析逗号分隔的文件

转载 作者:太空狗 更新时间:2023-10-29 15:19:52 25 4
gpt4 key购买 nike

我有一个包含类似数据的文件 -

Name, Age, Occupation
John, 14, Student
George, 14, Student
William, 23, Programmer

现在,我想读取数据,以便将每个值(例如姓名、年龄等)作为字符串读取。
这是我的代码片段 -

....
if (!(ferror(input_fp) || ferror(output_fp))) {
while(fscanf(input_fp, "%30[^ ,\n\t]%30[^ ,\n\t]%30[^ ,\n\t]",
name, age_array, occupation) != EOF){
fprintf(stdout, "%-30s%-30s%-30s\n", name, age_array, occupation);
}
fclose(input_fp);
fclose(output_fp);
}
....

然而,这会进入一个无限循环,给出一些随机输出。
这就是我对输入转换说明符的理解。
%30[^ ,\n\t] -> 读取最长为 30 个字符且
包含空格的字符串,逗号、换行符或制表符。
我正在读取 3 个这样的字符串。
我哪里错了?

最佳答案

OP 的

fscanf(input_fp, "%30[^ ,\n\t]%30[^ ,\n\t]%30[^ ,\n\t]", ...

不使用文本文件中的 ',''\n'。随后的 fscanf() 尝试也失败并返回值 0,这不是 EOF,导致无限循环。


尽管 OP 要求使用 fscanf() 解决方案,但 fgets()/sscanf() 可以更好地处理潜在的 IO 和解析错误。

FILE *input_fp;
FILE *output_fp;
char buf[100];
while (fgets(buf, sizeof buf, input_fp) != NULL) {
char name[30]; // Insure this size is 1 more than the width in scanf format.
char age_array[30];
char occupation[30];
#define VFMT " %29[^ ,\n\t]"
int n; // Use to check for trailing junk

if (3 == sscanf(buf, VFMT "," VFMT "," VFMT " %n", name, age_array,
occupation, &n) && buf[n] == '\0') {
// Suspect OP really wants this width to be 1 more
if (fprintf(output_fp, "%-30s%-30s%-30s\n", name, age_array, occupation) < 0)
break;
} else
break; // format error
}
fclose(input_fp);
fclose(output_fp);

与其调用 ferror(),不如检查 fgets()fprintf() 的返回值。

怀疑 OP 未声明的字段缓冲区是 [30] 并相应地调整了 scanf()


[编辑]

关于 if (3 == sscanf(buf, VFMT ","... 的详细信息

if (3 == sscanf(...) && buf[n] == '\0') { 在以下情况下变为真:
1) 正好是 3 个 "%29[^ ,\n\t]" 格式说明符,每个 scanf 至少有 1 个 char
2)buf[n]是字符串的结尾。 n 通过 "%n" 说明符设置。 "%n" 中前面的 ' ' 会在最后一个 "%29[^ ,\n\t]" 之后产生任何后续空白> 被消费。 scanf() 看到 "%n",它指示它设置从扫描开始的当前偏移量,以分配给指向的 int通过&n

"VFMT ","VFMT ","VFMT "%n" 由编译器连接到
"%29[^ ,\n\t], %29[^ ,\n\t], %29[^ ,\n\t] %n"
我发现前者比后者更容易维护。

"%29[^ ,\n\t]" 中的第一个空格指示 sscanf() 扫描(消耗而不保存)0 个或更多白色- 空格(' ''\t''\n' 等)。其余指示 sscanf() 消耗并保存 any 1 到 29 char except ',' '\n''\t',然后追加一个'\0'

关于c - 使用 C 使用 fscanf() 解析逗号分隔的文件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21410500/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com