c编程语言中的gets函数存在问题
我正在用C语言创建一个简单的程序。 不幸的是,我现在对一段源代码有问题。 运行程序后,我无法在students结构中存储数据 我认为问题在于ADD_Students()函数中的get()函数。(第60行) 以下是我的源代码:(在windows 10中使用gnu gcc编译器的代码块)c编程语言中的gets函数存在问题,c,structure,fgets,gets,C,Structure,Fgets,Gets,我正在用C语言创建一个简单的程序。 不幸的是,我现在对一段源代码有问题。 运行程序后,我无法在students结构中存储数据 我认为问题在于ADD_Students()函数中的get()函数。(第60行) 以下是我的源代码:(在windows 10中使用gnu gcc编译器的代码块) 您的代码中有一个问题。 您正在向get传递一个未初始化的指针 您从未向Addr\u INFO条目添加实际内存位。 您应该将成员声明为具有适当大小的数组,或者将数据获取到本地缓冲区,然后分配内存(malloc)将本地
您的代码中有一个问题。 您正在向
get
传递一个未初始化的指针
您从未向Addr\u INFO
条目添加实际内存位。
您应该将成员声明为具有适当大小的数组,或者
将数据获取到本地缓冲区,然后分配内存(malloc
)将本地数据复制到该缓冲区,并将其指针指定给成员。第一个问题-决不使用获取。从2011年标准开始,它已经从标准库中删除,并且它将(不是可能,将)在您的程序中引入故障点。它是钚的编程等效物。改用fgets
:
if ( fgets(Addr_INFO[i].Name, MAX_NAME_LEN, stdin) == NULL )
// error on input
else
// process Addr_INFO[i].Name
第二个问题-您从未留出任何内存来实际存储名称、字段或城市。您所做的只是声明指针,但从未将它们设置为指向任何有意义的地方。它们最初包含一些很可能与有效地址不对应的随机位模式
对于这样一个简单的程序,最好将这些字段声明为char
数组,而不仅仅是指针:
#define MAX_NAME_LEN 40 // or whatever you expect the longest name to be
#define MAX_FIELD_LEN 40 // same as above
#define MAX_CITY_LEN 40 // same as above
struct Students
{
char Name[MAX_NAME_LEN + 1]; // +1 for string terminator
char Field[MAX_FIELD_LEN + 1];
char City[MAX_CITY_LEN + 1];
unsigned int Student_ID;
float Mark;
}Addr_INFO[MAX];
然后,您的fgets
调用会稍微更改为
if ( fgets( AddrInfo[i].Name, sizeof AddrInfo[i].Name, stdin ) == NULL )
// error on input
else
// process AddrInfo[i].Name
请解释问题的性质;如果您收到错误消息,它会说什么?如果它产生了错误的结果,它是什么?它应该是什么?当您使用调试器运行它时,程序错误执行的第一件事是什么?调用scanf()
将换行保留在输入缓冲区中。因此,gets()
读取到第一个换行符。而且你永远不应该使用get()
!决不,决不,决不,决不,决不,决不使用get()
@乔纳坦利弗勒——有吗?;)它已弃用-还存在缓冲区溢出问题使用fgets()
,但您仍需要处理scanf()
和%c
留下的换行符。以及通过fgets()
输入的新行。ex nihilo链接的问答解释了问题CC GCC和替代方案。这是问题之一。至少还有两种,一种是使用gets()
。gets
至少应该是fgets
#define MAX_NAME_LEN 40 // or whatever you expect the longest name to be
#define MAX_FIELD_LEN 40 // same as above
#define MAX_CITY_LEN 40 // same as above
struct Students
{
char Name[MAX_NAME_LEN + 1]; // +1 for string terminator
char Field[MAX_FIELD_LEN + 1];
char City[MAX_CITY_LEN + 1];
unsigned int Student_ID;
float Mark;
}Addr_INFO[MAX];
if ( fgets( AddrInfo[i].Name, sizeof AddrInfo[i].Name, stdin ) == NULL )
// error on input
else
// process AddrInfo[i].Name