fclose()导致分段错误

fclose()导致分段错误,c,file-io,segmentation-fault,fopen,fclose,C,File Io,Segmentation Fault,Fopen,Fclose,我一直在尝试用C语言进行简单的文件处理,我想确保可以使用该语言访问该文件 #include<stdio.h> main() { CheckFile(); } int CheckFile() { int checkfile=0; FILE *fp1; fp1 = fopen("users.sav","r"); if(fp1==NULL) { fopen("users.sav","w"); fclos

我一直在尝试用C语言进行简单的文件处理,我想确保可以使用该语言访问该文件

#include<stdio.h>

main()
{
    CheckFile();
}

int CheckFile()
{
    int checkfile=0;

    FILE *fp1;
    fp1 = fopen("users.sav","r");

    if(fp1==NULL)
    {
        fopen("users.sav","w");
        fclose(fp1);
    }   
    if(checkfile!=0)printf("\nERROR ACCESSING FILE!\nNow exiting program with exit code: %d\n",checkfile);exit(1);
    return 0;
}
但是,如果文件事先已经存在(例如,当我手动创建它或当我第二次运行程序时),它不会出错

请帮忙。我需要在一周内完成我们的最后一个项目,但我还没有掌握文件和指针的窍门

我正在使用“gcc(Ubuntu/linaro4.8.1-10ubuntu9)4.8.1”

附言

我知道显然存在类似的问题,但请不要对此投反对票。我已经开始编写代码几个月了,因此无法理解那些高级代码和其他东西

p、 附言

我在另一个问题中看到了这一点

在原始代码中无法保证fopen实际工作,在这种情况下,它将返回NULL,并且不会定义fclose


那么,我如何确切地检查它是否工作?

fopen
返回一个
文件
指针。它将返回
NULL
,并设置全局
errno
,以指示错误。如果要检查
errno
,必须在检查
fopen
是否返回
NULL
后检查是否返回

if (fp1 == NULL)
{
    printf("fopen failed, errno = %d\n", errno);
}
否则,您可能会从其他地方得到一个
errno
,而不一定是您的
fopen
调用。还包括
errno.h
。您也不需要调用
fopen(“users.sav”,“w”)再次。您既不会重新分配指针,也不会再次检查它

我看不出有什么理由在这里调用
fclose
,因为如果
fopen
返回
NULL
,就没有任何东西可以关闭。这可能就是你seg故障的原因。您正在尝试关闭空指针

对代码的另一个注释。如果要从
CheckFile
返回
int
,则失败时可能不会返回
0
。我将返回
-1
以指示错误。更好的是,您可以返回全局
errno
。另外,
main
应该是
intmain()
并且应该
返回0在末尾。我并不特别喜欢你的
CheckFile
命名方案。在C语言中,
check_file
check file
的情况会更好

CheckFile
中,如果将一行
if
语句格式化为多行,则该语句可以更正常地工作。它不做你认为它现在做的事情:

if(checkfile!=0)
{
   printf("\nERROR ACCESSING FILE!\nNow exiting program with exit code: %d\n", checkfile);
   exit(1);
}

而且,
checkfile
永远不会设置在代码中的任何位置。。除了零。因此,
if
语句中的代码将不会执行,句号。

当fp1为NULL时调用
fclose(fp1)
这是正常的

顺便说一句


没有用,因为您没有将返回值分配给文件指针。这意味着users.sav文件将被打开进行写入,但您将永远无法在其中写入任何内容。

fclose的手册页上显示-

如果stream参数为 非法指针,或描述符已传递给上一个 调用fclose()

错误出现在代码中的
if
块中

if(fp1==NULL)
{
    fopen("users.sav","w");
    fclose(fp1);  // passing NULL to fclose invokes undefined behaviour
}   

我不确定你想做什么,但眼前的问题是:

if(fp1==NULL)
   fclose(fp1);
在断言fp1为NULL之后,您试图在NULL指针上调用
close
,这将导致分段错误


如果您只想验证文件是否存在,请尝试类似于另一个不相关的问题:

这一行可能不是您想要的:

if(checkfile!=0)printf("\nERROR ACCESSING FILE!\nNow exiting program with exit code: %d\n",checkfile);exit(1);
如果我们将其正确格式化,错误就会变得明显:

if (checkfile != 0)
  printf("\nERROR ACCESSING FILE!\nNow exiting program with exit code: %d\n",checkfile);

exit(1);
return 0 ;
实际上,即使
checkfile
为零,我们也将进入
exit(1)

你可能想要这个:

if (checkfile != 0)
{
  printf("\nERROR ACCESSING FILE!\nNow exiting program with exit code: %d\n",checkfile);
  exit(1); 
}

return 0 ;

结论:正确设置代码格式,许多错误会突然变得明显。

检查是正确的,只要不要
fclose(fp1)
if
fp1==NULL
而调用
fp1=fopen(…,“w”)谢谢:)这些答案真的帮了我。到目前为止,编码工作进展顺利。你可能会有重复的答案,你应该把它放到你的另一个答案中,很好的回答:)@GIJoe:嗯,我不确定我是否应该这样做,因为这个问题与原来的问题完全无关。我会。。让你的答案更有力。它确实。。。它还指出了我的代码中许多我没有注意到的其他复杂问题(因此它没有包括在我的问题中),但可能也会困扰我。。。我想这最后一个项目真的让我很紧张。
if (checkfile != 0)
  printf("\nERROR ACCESSING FILE!\nNow exiting program with exit code: %d\n",checkfile);

exit(1);
return 0 ;
if (checkfile != 0)
{
  printf("\nERROR ACCESSING FILE!\nNow exiting program with exit code: %d\n",checkfile);
  exit(1); 
}

return 0 ;