【问题标题】:Segmentation fault in fscanf() functionfscanf() 函数中的分段错误
【发布时间】:2014-05-26 16:53:29
【问题描述】:

我正在为 C 字搜索程序编写一些代码,在编译其中一个文件时,我在 fscanf 函数上遇到分段错误,但我不知道错误在哪里。 我已经搜索过答案,并且我明白在整数变量上我必须初始化它们的值(我已经完成了),并且我必须使用 '&' 引用 fscanf() 中的类型(也完成了)。

这是代码(在 main() 函数中):

int i;
int nl = 0;
int nc = 0;
int a, b, d;
char mat[1000][1000];//character matrix for wordsearch letters
int x[1000], y[1000];
int l, c, n;
printf("Chose the wordsearch you want to use.\n For example: t01.in, t02.in, t03.in,   t04.in, (...),t30.in\n");
char wordsearch_file[8];
fgets(wordsearch_file,8,stdin);//user enters f.e. 't01.in' 
FILE *stream;
char buffer[1024];
sprintf(buffer, "home/adminuser/Desktop/LA/ETAPA2/sopas/%s", wordsearch_file);
stream = fopen(buffer,"r");
if((fscanf (stream,"%d%d", &nl, &nc)) > 0){ // SEG. FAULT happens here
for(l = 0; l < nl; l++) {
    for(c = 0; c < nc; c++)
        mat[l][c] = fgetc(stream) != EOF;
    fgetc(stream);
}
}

我希望“nl”(行数)读取 3,而“nc”(编号 os 列)读取其他 3。

“t01.in”文件:

3 3
SIA
ORR
EDI

【问题讨论】:

  • 您检查文件是否存在并成功打开?您的完整地址开头可能缺少斜杠。
  • buffer 包含换行符。所以stream = fopen(buffer,"r"); 失败了。
  • 你是对的。我更改了那部分代码,一切正常。谢谢!

标签: c segmentation-fault scanf


【解决方案1】:

每当您打开外部资源(文件、数据库、套接字)或进行任何系统调用时,您始终会检查有效的流或返回代码。

您应该做的第一件事是添加对流的检查,而不是在不知道 fopen() 调用是否成功的情况下盲目调用 fscanf(stream,...)。

然后确定 fopen() 失败的原因。我建议打印出文件名,或检查它是否存在,和/或使用 perror() 打印系统错误。 perror() 会准确地告诉你出了什么问题,如果我不得不猜测的话,就像@BLUEPIXY 提到的那样,文件名中的换行符。

stream = fopen(buffer,"r");
if(!stream) {
    perror("what the problem: "); 
}

最后,学习如何使用调试器分析核心文件。如果您没有获得核心转储,请正确设置 ulimit。从记忆中,你想要“ulimit -c unlimited”。只需在 shell 提示符下键入“ulimit”即可找出您当前的 ulimit。然后重新运行你的崩溃程序。获得核心文件后,在其上运行 GNU 调试器。

gdb program.exe core

【讨论】:

  • @BLUEPIXY 是对的!就像你说的:文件名最后有'\n'所以'stream'没有打开。我改变了“fgets(wordsearch_file,8,stdin);”用 "scanf("%s\n",wordsearch_file);"它做得很好。谢谢!
  • 您仍然需要添加错误检查以确保流是打开的(非 NULL)。
猜你喜欢
  • 2018-10-08
  • 2011-05-25
  • 2017-03-29
  • 2015-02-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多