是的,所以我通过做一个基于小文本的RPG游戏学习语言的想法与C一起搞砸了.我按照Java的方式执行游戏的步骤,但有一些不同的解决方法,直到我遇到输出第一个字符串被我输入的第二个字符串部分覆盖的问题.这是问题发生的位(我猜).
struct character{
char firstname[100];
char lastname[100];
};
int main(){
struct character charname;
char first=charname.firstname[100];
char last=charname.lastname[100];
printf("And what do they call you?(First name)\n");
scanf("%s", &first);
printf("Any other names?(Last name)\n");
scanf("%s", &last);
printf("So you are called ");
printf("%s ", &first);
printf("%s ", &last);
return 0;
}
Run Code Online (Sandbox Code Playgroud)
我得到的输出是:
他们叫你什么?(名字)鲍勃
还有其他名字吗?(姓)Dole
所以你被称为BDole Dole
我不是BDole Dole而是Bob Dole !!!
有任何想法吗?
(刚刚意识到这里的代码输入有多可怕)
当你这样做
char first=charname.firstname[100];
Run Code Online (Sandbox Code Playgroud)
从包含100个字符的数组中获取字符101(请记住,数组索引从零开始).仅此一点是未定义的行为.
然后通过使用&first
不是指向数组的指针,甚至超出数组,而是指向局部变量的指针,使情况更糟first
在内存中的位置,将字符串写入此位置将覆盖堆栈上的内存,导致非常严重的问题.
你可能想要的是例如
char *first=charname.firstname;
Run Code Online (Sandbox Code Playgroud)
但这甚至不需要,因为数组自然地衰减指向它们的第一个元素,这意味着这是完全有效的:
scanf("%99s", charname.firstname);
Run Code Online (Sandbox Code Playgroud)
请注意"%99s"
格式,它告诉scanf
不要读取超过99个字符,因此它不会写入超出提供的缓冲区的末尾.