C 为什么会出现“分段错误(堆芯转储)”

C 为什么会出现“分段错误(堆芯转储)”,c,C,我是C编程新手,我正在尝试用linux编写一个程序 #include <stdio.h> #include <stdlib.h> char num, fileName[260]; int numCount, inp; FILE *fp, *nf; int main(int argc, char *argv[]){ printf( "1. New file\n" ); printf( "2. Display file\n" );

我是C编程新手,我正在尝试用linux编写一个程序

#include <stdio.h>
#include <stdlib.h>



 char num, fileName[260];
   int numCount, inp;
   FILE *fp, *nf;


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




   printf( "1. New file\n" );
   printf( "2. Display file\n" );
   printf( "3. Edit file\n" );
   printf( "4. Exit\n" );
   scanf( "%d", &inp );



   switch (inp){
    case 1:            
        displayFile();
       break;
    case 2:            
        printf("\n");
        break;
    case 3:            
        printf("\n");
        break;
    case 4:            
        printf("\n");
        break;
    default:            
        printf("\n");
        break;
   }




   fclose(fp);
   return 0;
}



int displayFile(void){

    printf("Enter the name of file. \n");
    scanf("%s",fileName);
    fp = fopen(fileName,"r");


    if(!fp){

        printf("Error! Cannot open file \n");
        exit(1);
   }

    else{
        printf("The content of %s are :\n", fileName);

        while( ( num = fgetc(fp) ) != EOF ) //End-of-file
            numCount++;
            printf("%c",num);

    }
        printf("There are %i numbers in file:\n", numCount);

}
这是我运行程序时发生的情况: 它开始,给我案例选择,我选择显示文件,它给我输入文件名。但是,在出现堆芯转储错误消息之前,我没有写入的选择。

当您选择2时。显示文件,fp未赋值,其值为NULL,因为它是未显式初始化的全局变量

当传递NULL时,fclose似乎会崩溃

比如说,

#include <stdio.h>

FILE *fp;


int main(void){
   fclose(fp);
   return 0;
}
已在上发出分段错误

我认为您不应该在main函数中关闭文件,而应该在displayFile函数中关闭文件


此外,您不应该有太多全局变量:您应该将其中一些变量设置为局部变量。

您的程序在方法上是非常错误的,您不需要在程序中声明单个全局变量

这些问题包括:

您没有为displayFile提供可能导致未定义行为的声明原型,如果启用了编译器警告,编译器将警告隐式函数声明

使用全局变量会使您的代码变得混乱,并可能出现错误

在一个函数中打开文件,在另一个函数中关闭文件,并且在调用fclose之前不检查NULL,因为将NULL传递给fclose是未定义的行为,所以这似乎是实际问题

在一个函数中打开文件,在另一个函数中关闭文件,这在概念上是错误的。由于第2点,这在你的程序中成为可能

全局变量是危险的,因为很难跟踪它们的状态,您可以在一个函数中修改它,而在另一个函数中使用它时会忽略它。此外,很少需要全局变量

您从不检查scanf的返回值,在第一次scanf中,这是非常危险的,因为它会在读取inp时导致未定义的行为


显示文件的编号为2,但不应给出文件的输入名称。你到底选择了什么?我不明白-我到底选择了什么?因为你的程序有一个bug,我不能写程序应该显示的文件名?使用全局变量有什么原因吗?我还应该把它们放在哪里?在最小的相关代码块中,像这样控制它们更容易。例如,fd仅在displayFile中使用。对于纯C,最小的相关代码块将是一个函数。将fclose放在displayfile中会导致程序在我选择displayfile时立即退出小心!在这句话中你自相矛盾:它的值是空的,因为它是全局变量,没有显式初始化。未初始化的值不为NULL,我甚至认为fclose一个NULL文件指针是被明确允许的-它崩溃是因为fd不为NULL。当NULL传递给fclose in时,程序崩溃。@Jongware fcloseNULL;盖伊:然后我把它和免费的混淆了。不过,迈克的说法是误导性的。fcloseuninitialized_变量;正如我说的,我是C语言的新手,现在我意识到我的代码乱七八糟。但是我不明白NULL如何传递到fclose。还有你添加的代码;选择选项2后关闭。对于一种语言来说,不熟悉并不能正确地编写难看的代码。这应该是你的优先事项之一。你解决问题了吗?关于选项,这是你自己的代码。还没有。我没有得到堆芯转储错误,但它会在我选择选项2Oh wait时立即关闭!我明白了,它正在工作。谢谢您的帮助,如果您认为这是有益的,请接受答案。谢谢你的评论是不必要的,实际上不鼓励这样做。你拿了那本书吗?
#include <stdio.h>
#include <stdlib.h>

int displayFile(void);
int main(int argc, char *argv[])
{
    int inp;

    printf( "1. New file\n" );
    printf( "2. Display file\n" );
    printf( "3. Edit file\n" );
    printf( "4. Exit\n" );

    if (scanf("%d", &inp) != 1)
        return -1;
    switch (inp)
    {
    case 1:
        displayFile();
        break;
    case 2:
        printf("\n");
        break;
    case 3:
        printf("\n");
        break;
    case 4:
        printf("\n");
        break;
    default:
        printf("\n");
        break;
    }
    return 0;
}

int displayFile(void)
{
    FILE *fp;
    char fileName[100];
    int numCount;
    int num;

    printf("Enter the name of file. \n");
    scanf("%99s", fileName);

    fp = fopen(fileName, "r");
    if (fp != NULL)
    {
        printf("The content of %s are :\n", fileName);
        while (( num = fgetc(fp)) != EOF)
            numCount++;
        printf("%c", num);
        printf("There are %i numbers in file:\n", numCount);
        fclose(fp);

        return 0;
    }
    return -1;
}