当我运行该程序时,第二个printf()
打印string2
,扫描到附加到末尾的string1
。
e.g。已将123
扫描到string1
,然后打印:Is before "12ab123"
。
而不是12ab
。
为什么不只是"12ab"
?
char string1[MAX_STR_LEN];
char string2[4]={'1','2','a','b'};
char five='5';
char abc[3]={'a','b','c'};
printf("Enter a string:");
scanf("%s", string1);
printf("Is before \"%s\":",string2);
答案 0 :(得分:3)
字符串是C中的空终止字符数组。
更改
function generatePlayerId(){
var tempId;
do{
tempId = Math.floor(Math.random()*7)+1;
} while (id.indexOf(tempId) !== -1);
return tempId;
}
到
char string2[4]={'1','2','a','b'};
(与char string2[5]={'1','2','a','b', '\0'};
相同)
答案 1 :(得分:1)
您需要使用NULL character
作为
char string2[5]={'1','2','a','b','\0'};
当您执行scanf()
时,string1
存储在下一个内存中,因此正在使用string2
打印string1
。它会打印到\0
所以Undefined Behavior
答案 2 :(得分:1)
在您的代码中
char string2[4]={'1','2','a','b'};
string2
不会以空值终止。使用 array 作为%s
格式说明符的参数会调用未定义的行为,因为它在搜索空终止符时会超过分配的内存。
您需要自己添加null-terminator,如
char string2[5]={'1','2','a','b','\0'};
将string2
用作字符串。
另外,您也可以写
char string2[ ]= "12ab";
允许编译器决定大小,它考虑(并添加)空终止符的空间。
同样适用于abc
。
那就是说,你扫描进入string1
并打印string2
,这当然没有错,但也没有多大意义。
答案 3 :(得分:1)
扩展前面的答案,由于变量在堆栈存储器中存储的顺序,字符串似乎已合并。在每种处理器体系结构或编译器上,这种效果并不总是相同的(优化器设置也可以更改此行为)。
答案 4 :(得分:0)
如果格式说明符%s
没有精度标志,则函数输出字符,直到遇到零字符'\0'
字符数组string2
的定义方式是它没有终止零
char string2[4]={'1','2','a','b'};
因此该函数输出数组之外的字符,直到它符合零字符。
您可以使用精确标志来明确指定要输出的字符数。例如
printf("Is before \"%4.4s\":",string2);
或者您可以定义包含终止零的数组。例如
char string2[5] = { '1', '2', 'a', 'b', '\0' };
考虑到在这种情况下,如果指定数组的大小应该至少等于5(尽管大小可以大于5;在这种情况下,没有初始化器的其他字符将为零 - 初始化)
或只是
char string2[] = { "12ab" };
或没有大括号
char string2[] = "12ab";