C字符串互相覆盖

时间:2015-10-04 12:45:19

标签: c string merge overwrite

是的,所以我通过做一个基于小文本的RPG游戏来学习语言的想法。我按照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;
}

我得到的输出是:

  

他们叫你什么?(名字)   鲍勃

     

还有其他名字吗?(姓氏)   多尔

     

所以你被称为BDole Dole

我不是BDole Dole,而是Bob Dole!

有什么想法吗?

(刚刚意识到这里的代码输入有多可怕)

2 个答案:

答案 0 :(得分:5)

当你这样做时

char first=charname.firstname[100];

从包含100个字符的数组中获取字符101(请记住,数组索引从零开始)。仅这一点就是未定义的行为

然后使用&first使指针不在数组中,甚至超出数组,但是指向局部变量first在内存中的位置,将字符串写入这个位置会覆盖堆栈中的内存,并导致非常严重的问题。

你可能想要的是什么。

char *first=charname.firstname;

但这甚至不需要,因为数组会自然地衰减到指向第一个元素的指针,这意味着它完全有效:

scanf("%99s", charname.firstname);

注意"%99s"格式,它告诉scanf不能读取超过99个字符,因此它不会超出提供的缓冲区的末尾。

答案 1 :(得分:0)

这不符合你的想法:

char first=charname.firstname[100];
char last=charname.lastname[100];

你可能要做的就是创建一个char的数组[100],就像你在Java中使用" new"运营商。但是C并没有这样做。 struct定义告诉编译器一个" struct字符"其中有两个100字符的字符串,所以当你写

struct character charname;

保留这两个字符串的空间。在需要之前,在堆栈上。它没有初始化,但它在那里,它属于结构。

因此,您现在可以通过调用scanf来填充这些数组。请注意,没有&或[]是必需的;该阵列据说是'衰变"用作其值时指针。

scanf("%s", charname.first);
/* later... */
scanf("%s", charname.last);

但是,使用fgets()通常更聪明 - 请参阅this C FAQ entry

除此之外,看起来您可能正在尝试通过采用类似Java的代码并随意修改它来学习C,直到它编译为止。这不起作用,特别是在C语言中。在某些语言中,通过听编译器告诉你的内容,你可以很好地了解什么是合法的;但是C有一个相对较弱的类型系统,所以它不能告诉你何时做一些愚蠢的事情。