如何在此处删除SEGFAULT?

时间:2014-01-22 08:02:23

标签: c segmentation-fault

我创建了一个打印文件内容的函数:

void readFile(char* filename)
{
int c ; 
file = fopen(filename, "r");    
printf("The contents of the file are:\n");
while((c = fgetc(file)) != EOF)
{
    printf("%c", c);
}   
return;

}

其中file是全局变量。 GDB提供如下输出:

_IO_getc (fp=0x0) at getc.c:39
39  getc.c: No such file or directory.
(gdb) bt
#0  _IO_getc (fp=0x0) at getc.c:39
#1  0x000000000040075e in readFile ()
#2  0x00000000004006d4 in main ()

但是,该文件存在,我在打印文件内容后得到SEGFAULT 可能因为这里的缓冲区(c)很小但我不确定。另外,即使是这样,我也不知道如何解决这个问题。任何人都可以建议我如何进行?

修改 我只调用一次readFile函数。这是我的呼叫功能:

int main(int argc, char* argv[])
{
char * filename;

filename = argv[1];
readFile(filename);
printf("File Handler: %ld", (long)file);

fclose(file);
return 0;
}

4 个答案:

答案 0 :(得分:2)

您传入的文件名不存在或由于其他原因无法打开。通过检查错误来摆脱段错误(为了这个,你还需要#include <errno.h> and <string.h>

void readFile(char* filename)
{
  int c ; 
  file = fopen(filename, "r");    
  if (file == NULL) {
     printf("Cannot open file '%s' : %s\n", filename, strerror(errno));
     return;
  }
  printf("The contents of the file are:\n");
  while((c = fgetc(file)) != EOF)
  {
      printf("%c", c);
  }   
  return;
}

答案 1 :(得分:1)

您的文件很可能是NULL,而您仍在尝试阅读。

我在删除此文件时模拟了此行为(SEG错误)。

如果文件存在,那么您的代码可以正常工作。

检查您传递的路径..如果您使用单\尝试\\,看看是否有效。第一个\将用作转义序列,最终路径将作为D:\temp\use.dat发送到fopen

readFile("D:\\temp\\user.dat");

答案 2 :(得分:0)

在对文件执行任何操作之前,必须确保已成功打开它。这是通过检查通过调用fopen收到的文件指针不是NULL来完成的。

执行此操作后,您将使用您选择的任何函数进行阅读,直到它返回指示无法阅读的值为NULL指针fgets0或{{1} } EOFfscanf EOF

在任何情况下,您都会以两种方式挑战这些返回值。第一种方法是使用fgetc检查读取错误。另一种方法是使用ferror检查文件的末尾是否已到达。

根据您的代码完成的完整程序:

feof

当然,通常你会在打开文件的同一个函数中关闭文件(例如#include <stdio.h> #include <errno.h> #include <stdlib.h> enum { OPEN_ERROR = 1, READ_ERROR }; enum { PARAM_EXIT = 1, OPEN_EXIT, READ_EXIT }; FILE *file = NULL; int readFile(char* filename) { int c; file = fopen(filename, "r"); if (file == NULL) return OPEN_ERROR; printf("The contents of file '%s' are:\n", filename); while((c = fgetc(file)) != EOF) printf("%c", c); /* * fgetc returns EOF on end of file and when an error occurs. * feof is used to determine whether the end of the file was reached. * Otherwise, we encountered a read error. */ if (feof(file)) c = 0; else c = READ_ERROR; return c; } int main(int argc, char *argv[]) { int status = 0; if (argc == 1) { fprintf(stderr, "usage: %s file\n", argv[0]); return PARAM_ERROR; } /* Check that <program ""> wasn't used... */ if (argv[1][0] == '\0') { fprintf(stderr, "error: empty filename detected, exiting. . .\n"); return PARAM_ERROR; } switch (readFile(argv[1])) { case 0: break; case OPEN_ERROR: fprintf(stderr, "error: file open failed - %s\n", strerror(errno)); status = OPEN_EXIT; break; case READ_ERROR: fprintf(stderr, "error: file read failed - %s\n", strerror(errno)); status = READ_EXIT; break; default: fprintf(stderr, "error: unknown error occurred, aborting...\n"); abort(); } if (file != NULL) fclose(file); return status; } 之类的文件,但当然会使用错误处理。)

答案 3 :(得分:-1)

我正在彻底改变我的回答

实际上,我正在阅读的文件是在gedit中打开的(这可能解释了为什么我在打印文件内容后得到了“NULL”。我关闭了文件并删除了NULL比较代码,它工作得很好。

好的,从每个人的评论中我都知道,当你阅读含有SEGFAULT内容的文件内容时,你基本上得到NULL。我刚刚在while循环中做了一个简单的修复:

while((c != EOF))
{
printf("%c", c);
c = fgetc(file);
if(c == NULL)
    break;
}

问题解决了! (虽然,编译器给我一个警告“指针和整数之间的比较”。)