为什么我的代码收到此消息“分段错误(核心已转储)”

时间:2020-08-06 06:58:16

标签: c

我试图在Linux中编写此c程序,但是当我运行该程序时,它将执行一半的代码,然后bash显示此消息“分段错误(内核已转储)” 这是代码:

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

int main()
{   
    char stName[30];
    int info[3];
    int showinfo()
   {
    printf("The name of the student is %s\n",stName);
    printf("The age of the student is %d",info[0]);
    int i = 1;
    while(i<4)
    {
     printf("The marks in subject %d is %d",i,info[i]);
     i++;
    }
   }
    int getinfo()
   {
    printf("Enter name of the student: ");
    gets(stName);
    printf("enter the age of the student %s : ",stName);
    gets(info[0]);
    for(int i=1;i<4;i++)
    {
     printf("Enter the marks in subjet %d",i);
     gets(info[i]);
    }
    return 0;
   }
    getinfo();
    showinfo();
    
}

输出如下:

Enter name of the student: Keshav
enter the age of the student Keshav : 20
Segmentation fault (core dumped)

1 个答案:

答案 0 :(得分:2)

您有很多小问题。首先"ISO C forbids nested functions",应在void showinfo()上方而不是其中声明/定义char *getinto()main()。接下来,必须确保在循环时不要尝试超出数组范围进行写操作。接下来,请参见:Why gets() is so dangerous it should never be used!它是如此不安全,并且容易被缓冲区溢出利用,因此对于C11库,它已被完全删除。

编写showinfo()时,它只不过是一个输出例程,不需要使该函数返回值。将返回类型更改为void可以使它更清楚。由于您现在要声明main()之外的函数,因此您需要将该函数中需要的变量作为参数传递,例如

#include <stdio.h>
#include <string.h>

#define MAXC 128   /* if you need a constant, #define one (or more) */
#define NFOC   4

void showinfo (const char *stName, int *info)
{
    printf ("\nThe name of the student is %s\n"
            "The age of the student is %d\n\n", stName, info[0]);
    
    for (int i = 1; i < NFOC; i++)
        printf ("  The marks in subject %2d is %2d\n", i, info[i]);
}

注意:,您只需要一个printf()调用即可输出两行文本。在编译过程中会连接相邻的文字字符串)

,对于getinfo()

char *getinfo (char *stName, int *info)
{
    fputs ("Enter name of the student: ", stdout);
    if (fgets (stName, MAXC, stdin) == NULL)
        return NULL;
    stName[strcspn (stName, "\r\n")] = 0;   /* trim trailing \n from end of stName */
    
    printf ("enter the age of the student %s  : ", stName);
    if (scanf ("%d", &info[0]) != 1)
        return NULL;
    
    for (int i = 1; i < NFOC; i++) {
        printf ("Enter the marks in subjet %d : ", i);
        if (scanf ("%d", &info[i]) != 1)
            return NULL;
    }
    return stName;
}

stName数组与info数组一起作为参数传递给函数以及上面的showinfo()。这里返回stName是为了方便起见,允许您根据需要使用printf变量列表中的函数。它返回NULL表示收集输入失败。

main()现在简化为:

int main (void)
{
    char stName[MAXC];
    int info[NFOC];
    
    getinfo (stName, info);
    showinfo (stName, info);
}

使用/输出示例

运行程序并在出现提示时提供输入,您将收到以下输出:

$ ./bin/nested
Enter name of the student: John Q. Student
enter the age of the student John Q. Student  : 21
Enter the marks in subjet 1 : 88
Enter the marks in subjet 2 : 87
Enter the marks in subjet 3 : 92

The name of the student is John Q. Student
The age of the student is 21

  The marks in subject  1 is 88
  The marks in subject  2 is 87
  The marks in subject  3 is 92

启用警告

始终在启用了警告的情况下进行编译,并且接受代码,直到在没有警告的情况下进行编译。要启用警告,请在您的-Wall -Wextra -pedantic编译字符串中添加gcc/clang(也可以考虑添加-Wshadow来警告阴影变量)。对于 VS (在Windows上为cl.exe),请使用/W3。所有其他编译器将具有类似的选项。阅读并理解每个警告-然后修复它。他们将确定任何问题以及发生问题的确切路线。通过听编译器告诉您的内容,您可以学到很多东西。

仔细检查一下,如果还有其他问题,请告诉我。