在 C 中以某种格式从文件中读入会产生段错误

Reading in from file in a certain format in C produces seg fault

目前,我正在尝试从代表数独谜题解决方案的文件中读取数字。该文件应该被格式化为 9 个数字,中间没有空格,后跟一个换行符,在第 80 个数字之后结束。

在阅读时,我正在使用 fscanf,我可以让它处理一个有效的谜题,但不能处理一个无效格式的谜题;那些产生分段错误。我试图检查数组的长度,但由于在我声明 s 时将其设置为 10,因此无法捕获太短或太长的字符串。我会以错误的方式解决这个问题吗?我将 post 下面的代码。

FILE* puzzlefile;
char s[10];
int i=0, j=0, skip;
int form;

//opens the file so we can access the puzzle
puzzlefile = fopen(argv[1], "r");

for (i=0; i<9; i++){
    form = fscanf(puzzlefile, "%s\n",s);
    for (j=0; j<10; j++){
        if (form == 0){
            printf("Invalid format on input. Bad newline.\n");
            return 1;
        }
        if(j<9){
            if(s[j] == '1' || s[j] == '2' || s[j] == '3' || s[j] == '4' || s[j] == '5' || s[j] == '6' || s[j] == '7' || s[j] == '8' || s[j] == '9'){
                puzzle[i][j] = (int)(s[j]-'0');
            }
            else{
                printf("Invalid format on input.\n");
                return 1;
            }
        }
    }
}

我是不是走错了路?如果是这样,我只是在滥用 fscanf() 吗?或者我应该使用另一种类型的输入功能吗?我正在测试的文件包括一些遵循格式但使用字母而不是数字的文件,一个在第一行有一个额外数字的拼图,一个每 5 个数字有一个换行符的拼图,以及一个全是数字但没有换行符的拼图。所有这些都会产生段错误。

  1. 您没有检查 puzzlefile 是否为 NULL,您应该确保文件已打开,以防它不是 fopen() returns NULL,所以检查 fopen() 的 return 值是一件非常重要的事情。

  2. 您似乎没有检查是否 argv[1] != NULL 如果您忘记向程序传递参数会发生这种情况,后果将是程序出现故障并且您将没有任何线索为什么。

  3. s的大小太小,容易溢出,让fscanf()知道目标字符串有多少space , 像这样

    form = fscanf(puzzlefile, "%9s\n", s);
    /*                          ^ 9 characters + '[=10=]' = 10 */
    
  4. 要防止读取到字符串末尾,请执行此操作

    for (i = 0 ; s[i] != '[=11=]' ; ++i)
    

    而不是

    for (i=0; i<10; i++)
    

    与内循环相同

  5. 如果你这样做就更好了

    if ((s[j] > '0') && (s[j] < 1 + '9'))
    

    而不是

    if(s[j] == '1' || s[j] == '2' || s[j] == '3' || s[j] == '4' || s[j] == '5' || s[j] == '6' || s[j] == '7' || s[j] == '8' || s[j] == '9')
    

你没有 post puzzle 的声明,如果你在它结束后写它也可能是问题,你应该非常小心在 c 中进行绑定检查,因为写过去缓冲区的末尾,没有定义的行为,在某些情况下,当你测试它时不会发生任何坏事,当然错误会静静地留在那里直到它爆发。