当我尝试将一个元素从char数组复制到char然后从同一char复制到另一个char数组时,第二个char数组给出了奇怪的输出,通常包含第一个char数组中的整个字符串。仅当第二个char数组未初始化时,才会发生这种情况。我的问题是char如何将整个字符串传输到另一个char数组。
int main()
{
char a[10] = "ababababa";
char b[5];
char temp;
temp=a[1];
b[0]=temp;
std::cout<<b;
}
使用g ++时,我得到b{�Uarabababa
使用clang ++时,我得到b�U
每次运行程序时,b
和U
之间的内容都会更改。
答案 0 :(得分:1)
char b[5];
在这里,b
是5
,未初始化 char
s的数组。在初始化它们之前检查它们的值会导致不确定的行为。
temp=a[1];
b[0]=temp;
在这里,您 initialise 仅分配给b
的第一个元素。其余的 still 尚未初始化。
std::cout<<b;
在这里,您将b
用作数组,由于数组衰减,std::cout
将其解释为c字符串(实际上,std::cout
看到了const char*
,默认情况下,假定为以空值结尾的c字符串)。由于它需要检查直到null终止符内部的所有元素的值,因此它会执行 undefined bahaviour (未定义行为),因为某些值未初始化。
调用未定义行为的程序无法预测其结果。从字面上看,任何事情都可能发生,包括在不同编译器上的不同行为,甚至在执行之间的不同行为。
答案 1 :(得分:0)
b
中的字符未初始化,因此它们不太可能包含空字符。您将第一个字符初始化为'b'
,然后打印数组。
调用char *
流运算符,该运算符通过扫描字符串来确定字符串的长度,直到找到空字符为止。由于数组不包含空字符,因此它将继续读取数组的末尾内容,直到碰巧在其他地方找到空字符为止。在您的情况下,看来您的编译器已将a
存储在堆栈中的b
之后,因此它会打印b
的所有元素,以及其他一些字符(也许填充了b
到内存中的偶数字节),然后a
的内容,在a
末尾的空终止符处停止。不能保证所有这些,并且会在编译器,操作系统甚至程序的不同运行之间改变。欢迎来到不确定行为的世界。
简单的解决方法是在程序开始时将b
初始化为全零:
#include <algorithm>
#include <iostream>
int main()
{
char a[10] = "ababababa";
char b[5];
std::fill(std::begin(b), std::end(b), '\0');
char temp;
temp=a[1];
b[0]=temp;
std::cout<<b;
}
或者用std::string
完全避免问题:
#include <algorithm>
#include <iostream>
int main()
{
std::string a = "ababababa";
std::string b( 1, a[ 0 ] );
std::cout<<b;
}