12

我一直在尝试在 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;
}

然后它显示

Segmentation fault (core dumped)

但是如果文件已经预先存在(例如当我手动创建它或当我第二次运行程序时)它不会出现段错误

请帮忙。我需要这个用于一周后到期的最终项目,但我还没有掌握文件和指针的窍门。

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

附言

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

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

那么我该如何检查它是否有效呢?

4

5 回答 5

8

这很正常,当您fclose(fp1)在 fp1 为 NULL 时调用。

顺便提一句

fopen("users.sav","w");

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

于 2014-03-19T12:58:52.600 回答
4

fopen返回一个FILE指针。它将返回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,没有什么可以关闭的。这可能是您的段错误的原因。您正在尝试关闭空指针。有关 fopen 失败的更多信息

对您的代码的另一条评论。如果您要返回intfrom CheckFile,它可能不应该0失败。我会返回-1以指示错误。更好的是,您可以返回全局errno. 此外,main应该是int main(),你应该return 0;在最后。我不是特别关心你的命名方案CheckFile。在 C 中,check_file还是 camelCase 的checkFile会更好。

在中,如果您在多行上对其进行格式化CheckFile,您的单行if语句可能会被格式化并且可以更正常地工作。它没有做你认为它目前所做的事情:

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

此外,checkfile永远不会在您的代码中的任何地方设置......除了零。所以if语句中的代码不会执行,句号。

于 2014-03-19T12:58:39.133 回答
2

我不确定您要做什么,但是直接的问题在这里:

if(fp1==NULL)
   fclose(fp1);

在断言 fp1 为 NULL 后,您尝试调用close空指针,这将导致分段错误。

如果您只想验证文件是否存在,请尝试检查文件是否存在于 C 中的最佳方法是什么?(跨平台)

于 2014-03-19T13:03:11.627 回答
0

另一个不相关的问题:

这条线可能不是你想要的:

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 ;

exit(1)实际上,即使checkfile为零,我们也会得到。

你可能想要这个:

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

return 0 ;

结论:正确格式化您的代码,许多错误会突然看起来很明显。

于 2014-03-19T13:09:41.723 回答
0

的手册页fclose说 -

如果流参数是非法指针,或者是已经传递给先前调用 fclose() 的描述符,则 fclose() 的行为未定义。

错误在if代码中的块中。

if(fp1==NULL)
{
    fopen("users.sav","w");
    fclose(fp1);  // passing NULL to fclose invokes undefined behaviour
}   
于 2014-03-19T13:02:59.843 回答