我有这段代码可以读取文件并将所有内容解析为人员列表:
PersonList *parseFile(FILE* file) {
PersonList *list = newPersonList();
int r;
do {
char fname[50];
char name[50];
char gender;
int birthYear;
int deathYear;
r = fscanf(file, "%50s %50s %1s %d %d", fname, name, &gender, &birthYear, &deathYear);
printf("%s %s %c %d %d\n", fname, name, gender, birthYear, deathYear);
// Stuff I want to do in future
} while (r != EOF);
return list;
}
文件格式如下:
亚历山大·沃尔纳 1922 年 1957 年伯特伦·霍尔比希勒 1905 年赫敏·沃尔纳 1904
string string char int int string string int string string int
所以,我试着找到那个人,然后是 parent 。奇怪的是 printf 没有打印出这个人的 fname。如果我在 fscanf 中更改 fname 和 name 的顺序,那么第一个字符串将保存在 name 中,但是第二个不在 fname 中。 这种好奇心取决于第 5,6 行中 faname 和 name 声明的顺序。如果我将它们翻转过来,name 将不再被填充。那是什么黑客?为什么我不能在 fname 中保存任何字符串? 希望有人能解释这种奇怪的行为。谢谢。
最佳答案
使用 %c
读取 char
而不是 %1s
作为 %s
总是 写入一个空终止符,因此代码具有 undefined behaviour ,这意味着任何事情都可能发生,因为它超越了 gender
的“界限”。同样,当 printf()
ing 将 %c
用于 char
类型的变量时(正如您正确拥有的那样)。
格式说明符 %Ns
中的宽度必须比目标缓冲区小一个以允许空终止字符。
更改为:
r = fscanf(file, "%49s %49s %c %d %d", ...
/* ^^ ^^ ^ */
在使用由 fscanf()
赋值的变量之前,通过检查 fscanf()
的结果确保它们实际上已经被赋值,返回成功赋值的次数(在这种情况下,5
是预期的):
if (r == 5)
{
printf("%s %s %c %d %d\n", fname, name, gender, birthYear, deathYear);
}
关于c - fscanf 的奇怪异常和变量声明的顺序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16743750/