c - fscanf 的奇怪异常和变量声明的顺序

标签 c variables declaration scanf

我有这段代码可以读取文件并将所有内容解析为人员列表:

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 中更改 fnamename 的顺序,那么第一个字符串将保存在 name 中,但是第二个不在 fname 中。 这种好奇心取决于第 5,6 行中 fanamename 声明的顺序。如果我将它们翻转过来,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/

相关文章:

c - 多线程上下文中的 assert() 安全性

PHP preg_replace 文本变量

arrays - BASH:将 $1 评估为字符串以调用数组长度

c - minGW 下 _rotl 性能较差

c - 执行 malloc 后将字符串传递给函数

c - 从字节数组中扫描字符串

python - 当作为参数传递给具有可变参数的函数时,列表解包如何工作?

c++ - 申报地点是什么意思?

c - Windows 套件错误

c++ - 带数组的列表( vector )定义