【问题标题】:How to fix the segmentation fault error 11 appearing after running my code?如何修复运行我的代码后出现的分段错误错误 11?
【发布时间】:2019-12-30 21:27:56
【问题描述】:

我正在尝试解决这个关于在 C 中将数据从一个文件移动到另一个文件的问题。运行该程序会给出一个segmentation error 11。我附上了问题的图片。 Exercise 4

我相信打开文件有问题,我在终端里面输入了C代码脚本名称:code.c file1.txt file2.bin -b。文件包含在路径中。

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>

int main(int argc, char** argv){

  size_t k;
  char read1[100] = {};
  FILE* s;
  FILE* d;
  if (argc < 4) {
    printf("NA");
    exit(1);
  }

  if (strcmp(argv[4], "-b") == 0) {
    printf("binary file output\n");
    d = fopen(argv[3], "wb");
    if (d == NULL) {
      printf("cant open d");
      exit(1);
    }
  } else {
    if (strcmp(argv[4], "-t") == 0) {
      printf("textual file output\n");
      d = fopen(argv[3], "w");
    } else {
      printf("error");
      exit(1);
    }
  }

  s = fopen(argv[2], "r");
  if (s == NULL) {
    printf("cant open s");
    exit(2);
  }
  k = fread(read1,  sizeof(char),100, s);
  while (k != 0) {
    fwrite(read1,  k,1, s);
    k = fread(read1,  sizeof(char),100, s);
  }
  fwrite(read1,  k,1, s);
  fclose(s);
  fclose(d);

  return 1;
}

我希望将所有数据从file 1 移动到file 2,并且file2 output 可以是二进制或文本,具体取决于用户输入流。忽略了“十六进制”大小写。

【问题讨论】:

  • 请不要张贴文字图片。将文本复制到问题中,这对屏幕阅读器更友好,可以轻松复制粘贴和执行差异,并且占用更少的空间。谢谢。
  • 在使用argv[4]之前,请检查argc。在您使用fread 之前,请检查fopen 是否返回了一个有效的指针。如果没有这些检查,您可能会遇到无法检测到的故障。另外:将变量 read 命名为与库函数相同是不明智的。
  • 如上所述,您还需要存储来自fread 的返回值并在fwrite 中使用它。另外,请参阅Why is while ( !feof (file) ) always wrong? 循环应该由来自fread 的返回值驱动。此外,您应该将第二个和第三个参数反转为freadfwritesizecount
  • 您已经修改了发布的代码,但它不再是真正的代码,因为访问argv[4] 需要argc5 或更多。而且,您还没有按照建议颠倒 freadfwrite 的参数。
  • 您没有更改fwrite,并且,循环之后不应该有任何fwrite。请小心。另外:sizeof (char) 定义为 1

标签: c file segmentation-fault


【解决方案1】:

您似乎想编写一个程序,该程序采用输入文件、输出文件和标志(-b-t)的名称,所以我猜您是这样调用程序的:

program infile outfile [-b|-t]

这是 3 个参数。它们将分别是argv[1]argv[2]argv[3]。您应该访问argv[4]。您的程序将在strcmp(argv[4], "-b") 上出现段错误。你所有的argv[x] 都应该向后移动一个。不过检查if (argc &lt; 4) 没问题。

另一个可能导致分段错误的事情是从无效的FILE* 中读取。您没有在第二个fopen() 之后检查d == NULL。你应该这样做,如果是NULL,就会出现错误退出。

除此之外,您的代码还有其他问题:

  1. 在退出 while 循环后,您不应调用 fwrite。你知道k == 0 不在循环中。它无害,但无用且不会打印任何内容。

  2. 您应该像这样重新排列fwrite 的参数:fwrite(read1, 1, k, s)

  3. 您最后的return 1 语句没有意义,您应该返回0,而不是1,以便成功执行程序。

  4. 您不需要使用char read1[100] = {}; 初始化数组,因为在覆盖其内容之前您不使用它。做char read[100];就好了。

PS:你应该learn to use GDB 来调试你的程序。使用 GDB 很容易发现像这样的问题,只需逐个执行说明即可。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-06-04
    • 1970-01-01
    • 2017-06-02
    • 1970-01-01
    • 2016-08-06
    • 2020-07-10
    • 1970-01-01
    相关资源
    最近更新 更多