以下代码是问题部分:
#define NICKLEN 10
...
typedef char * string;
typedef struct donation
{
string nickname;
...
} Item;
...
void eatline(void)
{
while (getchar()!='\n');
}
...
string s_gets(string st, int n)
{
string ret_val;
string find;
ret_val=fgets(st, n, stdin);
if (ret_val)
{
find=strchr(st, '\n');
if (find)
*find='\0';
else
eatline();
}
return ret_val;
}
...
int main(void)
{
Item donate;
...
puts("Enter y to start");
while(getchar()=='y')
{
eatline(); // to remove \n from input
puts("Enter nickname. Limit is 10 characters.");
s_gets(donate.nickname, NICKLEN);
...
以下是输入,输出
Enter y to start
y
Enter nickname. Limit is 10 characters.
ffff
当我输入昵称时,会发生错误(在gdb中):
iogetline.c: No such file or directory.
答案 0 :(得分:1)
nickname
或struct donation
中的成员Item
是char
指针。所以,donate.nickname
是一个未初始化的指针。它可能指向任何地方,因为它具有垃圾价值。
此指针中的值被视为内存位置的地址,该内存位置甚至可能不是允许程序访问的内存的一部分。
非法访问内存时,程序会出错。
在fgets()
中使用s_gets()
,您正在写入donate.nickname
指向的记忆位置。
您可以将struct donation
设为
typedef struct donation
{
char nickname[11];
...
} Item;
因为nickname
存储的字符串的最大大小为10.额外的一个字符用于\0
字符。
fgets()
也会在尾随\n
中读取。如果你想存储它,我想你必须将大小修改为12。
或者如果您想要动态内存分配,请在Item donate;
donate.nickname = malloc(sizeof(char)*11);
并在完成使用后释放内存
free(donate.nickname);