Linux 分段故障(核心转储)

Linux Segmentation fault (core dumped)

提问人:Catalin Ionita 提问时间:11/12/2023 最后编辑:Ulrich EckhardtCatalin Ionita 更新时间:11/12/2023 访问量:60

问:

我需要模拟 grep -f 命令在 2 个文件之间的效果 代码编译后没有错误,但是当我运行它而不是输出时,它显示分段错误(核心转储) 我怎么能这样?此外,如果您能以更好的方式打开 f1 和 f2,而无需使用 aux1 和 aux2 来提供文件名,那就太好了。提前致谢。

我知道我必须检查代码是否有足够的参数,如果没有,我应该用 stderr 做一些事情(这是我在课堂上被告知要做的,但我不知道怎么做)

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

int main(int argc, char *argv[])
{
  FILE *file1;
  FILE *file2;
  char aux1[100]="",aux2[100]="";
  strcpy(aux1,argv[1]);
  strcpy(aux2,argv[2]);
  file1 = fopen("aux1","r");
  file2 = fopen("aux2","r");

  char s1[100]="",s2[100]="";
  char aux[100]="";

  while(fscanf(file1,"%s",aux)!=EOF)
  {
    strcat(s1,aux);
    strcat(s1," ");
  }
  s1[strlen(s1)-1]='\0';

  while(fscanf(file2,"%s",aux)!=EOF)
  {
    strcat(s2,aux);
    strcat(s2," ");
  }
  s2[strlen(s2)-1]='\0';

  printf("%s\n",strstr(s2,s1));

  return 0;
}
C 文件 终端 分段 - 故障

评论

0赞 Dan Getz 11/12/2023
100 当然是一个很大的数字,但你确定它足以容纳你所有的琴弦吗?
0赞 Dan Getz 11/12/2023
此外,grep 说 -f 将“从文件中获取模式,每行一个”,我没有看到您检查任何一个文件中的行结尾。
0赞 Weather Vane 11/12/2023
这应该是(两个变化),其他行也是如此。while(fscanf(file1, "%s", aux) != EOF)while(fscanf(file1, "%99s", aux) == 1)
0赞 William Pursell 11/12/2023
当你得到一个核心转储时,你应该看看它。有时,您会有一些见解,并在看到发生核心转储后 10 毫秒意识到问题所在,而您不需要查看它。如果您没有获得这种洞察力,则大约需要 3 秒钟才能打开核心转储并获得回溯,这通常会向您准确显示问题所在,然后您获得必要的见解。了解如何查看核心转储是一项应该学习的关键技能。
0赞 William Pursell 11/12/2023
但在这种情况下,您不需要学习如何读取核心转储;你需要一个关于 C 语言的基本入门知识。

答:

1赞 Harith 11/12/2023 #1
  FILE *file1;
  FILE *file2;
  char aux1[100]="",aux2[100]="";
  strcpy(aux1,argv[1]);
  strcpy(aux2,argv[2]);
  file1 = fopen("aux1","r");
  file2 = fopen("aux2","r");
  • 在将命令行参数复制到 和 之前,不要检查是否提供了任何命令行参数。aux1aux2
  • 使用 and 作为文件的名称,而不是 和 的内容。你不需要这两个变量,只需直接传递和传递即可。"aux1""aux2"aux1aux2argv[1]argv[2]fopen()
  • 您不检查调用是否成功。 返回以指示失败。fopen()fopen()NULL
while(fscanf(file1,"%s",aux)!=EOF)
  {
    strcat(s1,aux);
    strcat(s1," ");
  }
  • 没有检查此串联是否超过 的长度,该长度仅足以容纳 100 个字符。此处需要动态分配。s1
printf("%s\n",strstr(s2,s1));
  • strstr()如果未找到子字符串,则返回。在将其返回值传递给 之前,不检查其返回值。NULLprintf()

我知道我必须检查代码是否有足够的参数,如果没有,我 应该用 stderr 做点什么(这是我在课堂上被告知要做的 但我不知道怎么做)

只需检查(参数计数)的值:argc

/* Change 3 according to your requirements. */
if (argc != 3) {
   fputs( /* Error message here. */, stderr); 
   return EXIT_FAILURE;
}
2赞 Weather Vane 11/12/2023 #2

这里有一个很大的错误:

strcpy(aux1, argv[1]); 
file1 = fopen("aux1", "r");

您没有打开传递的文件,并且在不检查它是否打开的情况下,您使用文件指针直接进入段错误。NULL

它应该是

file1 = fopen(aux1, "r");     // removed " marks
if(file1 == NULL)
    exit(1);

您还询问了如何避免使用哪些可以完成aux1

if(argc < 2)
    exit(1);
fopen(argv[1], "r");