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)
解决方案
你有很多小问题。首先"ISO C forbids nested functions"
,您应该声明/定义void showinfo()
及char *getinto()
以上main()
,而不是其中。接下来,您必须确保在循环时不会尝试超出数组的范围进行写入。接下来,请参阅:为什么 gets() 如此危险,永远不应该使用!它非常不安全,而且很容易被缓冲区溢出利用,它已被 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
启用警告
始终在启用警告的情况下进行编译,并且在没有警告的情况下编译之前不要接受代码。要启用警告,请添加到您的编译字符串(也可以考虑添加以警告阴影变量)。对于VS(在 Windows 上),使用. 所有其他编译器将具有类似的选项。阅读并理解每个警告——然后去修复它。他们将识别任何问题,以及它们发生的确切线路。通过聆听编译器告诉您的内容,您可以学到很多东西。-Wall -Wextra -pedantic
gcc/clang
-Wshadow
cl.exe
/W3
如果您还有其他问题,请仔细查看并告诉我。
推荐阅读
- linux - 使用“日期”命令转换整个列
- javascript - 为什么 redux 存储更改后连接的 React 组件不更新?
- python - NameError: name 'Address' 未定义(使用 python shell 时),但它在 models.py 中
- protractor - Protractor 无法编译 Typescript 但路径存在
- biginteger - 32-1024 位定点矢量算法与 AVX-2
- bash - 从 Linux bash 调用 Matlab 时捕获错误消息
- python - 如何获得每个问题的所有四个选项...例如,如果我打印问题,那么我如何打印该特定问题的所有四个选项
- python - 使用 os.path.join() 运行脚本时出现 TypeError
- java - ExecutorService InvokeAll 用于混合数据类型
- asp.net-core - ASP.NET Core 验证剃刀标记