【问题标题】:Segmentation fault when writing char array to file in C在C中将char数组写入文件时出现分段错误
【发布时间】:2020-09-14 23:58:30
【问题描述】:

当我运行以下代码时,我在fprintf(outfile, "%s", inputline[j]); 收到一个“分段错误”

我无法理解错误的原因。我对 C 比较陌生,有人可以帮我解决错误吗?

void test(char *inputline) {
    FILE *outfile = fopen("results.txt", "w");   
    if (!outfile) {
        perror("Error while opening file: ");
    } else {
        for (int j = 0; j < 20; ++j) { // I only want to be write the first 20 characters to the file that is why I have the iteration till only 20 and added [j], is that correct way to do it?
            fprintf(outfile, "%s", inputline[j]);
        }
    }
}

//Function call
    ...
    char inputline[40] = "hello world 123 456"; //passed to the function above
    test(inputline);

【问题讨论】:

  • 您将一个字符 (inputline[j]) 传递给 fprintf,但格式说明符需要一个字符串 (char *)。
  • 您为需要char* 指针的fprintf 提供了char。需要地址的char 的低值在取消引用时可能会出现段错误。你需要"%c"
  • 倒数第二行缺少分号,函数永远不会关闭。
  • 提示:更改示例代码完全不加备注帮助不大
  • @Anna 好的,但请发布真实代码,Minimal Reproducible Example,这是显示问题的最短完整代码。

标签: c segmentation-fault printf


【解决方案1】:

导致分段错误的代码中的错误是您将 charinputline[j] 传递给 printf 以获得 %s 参数,该参数需要一个字符串指针。这具有未定义的行为。

要最多写入字符串的前 20 个字符,您可以使用 %.20s 作为格式说明符。也不要忘记关闭文件:

void test(const char *inputline) {
    FILE *outfile = fopen("results.txt", "w");   
    if (outfile == NULL) {
        perror("Error while opening file: ");
    } else {
        // print at most 20 bytes from inputline
        fprintf(outfile, "%.20s\n", inputline);
        fclose(outfile);
    }
}

请注意,如果需要,此最大计数可以是具有%.*s 格式的变量:

        int limit = 20;
        fprintf(outfile, "%.*s\n", limit, inputline);

【讨论】:

    【解决方案2】:

    格式说明符%s in

    fprintf(outfile, "%s", inputline[j]);
    

    需要一个 char * 变量,但您实际上传递的是一个 charinputline 数组的 j th 元素)。

    出现分段错误的原因是fprintf 试图“访问”传递的字符指向的内存位置。由于它很可能是一个无效地址,操作系统会抱怨试图访问分配给您的应用程序的空间之外的内存。

    您可以按字符打印到文件字符,保持for循环并使用%c格式

     for(int j=0; j<20; ++j)
     {
         fprintf(outfile, "%c", inputline[j]);
     }
    

    或打印整个字符串保持%s 格式,传递整个数组并摆脱for循环:

    fprintf(outfile, "%s", inputline);
    

    注意:在第一种情况下,无论如何都会写入 20 个字符。在第二种情况下,“长度+1”字符是因为字符串终止符'\0'

    【讨论】:

    • 例如,如果我想使用 fprintf(outfile, "%c", inputline[j]); 并且我只循环 5 次,然后我想在 5 之后的最后一个字符上附加一个“-”,我该如何添加它逻辑?
    • @Anna 在循环内添加if (i == 5) fprintf(outfile, "%c", '-');
    • @RobertoCaboni 顺便说一句,i 不会在这里制作更好的循环变量吗? j 通常用于嵌套循环。此外,OP 甚至没有 j 的声明。
    • @RobertoCaboni 在问题下查看 WeatherVane 的 cmets,他们应该提供最小的可重现示例。如果有诸如缺少分号、缺少初始化程序之类的错误,您不应该将它们从他们的问题中编辑出来。在答案中更正并让他们知道所有错误。
    • @Anna:请不要为了修复错误而不断修改问题,这会使cmets和答案不一致。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-06-14
    • 2011-05-20
    • 1970-01-01
    • 2018-08-06
    • 1970-01-01
    相关资源
    最近更新 更多