copied/truncated 字符数组中的奇怪符号
Weird symbols in copied/truncated character array
#include <iostream>
using namespace std;
void truncate(char* s1, char* s2, int n) {
for (int i = 0; i < n; i++) {
s2[i] = s1[i];
}
}
int main() {
char s1[15] = "Hello World";
char s2[10];
int n{ 5 };
truncate(s1, s2, n);
cout << s2; // this should display: Hello
}
当我在 Visual Studio 中 运行 时,我得到这个输出:
Hello╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠Hello World
但是当我运行它使用在线编译器(在线GDB)时,输出是正常的:
Hello
我知道它与 [=14=]
终止符有关,但我就是想不通。
您的 truncate
函数不会将 所需的 nul
terminator character 添加到目标 (s2
) 字符串。因此,当您在 main
中调用 cout
时,它将继续打印字符,直到它在 garbage-initialized 数据之后的某个未指定位置找到预期的 nul
(零)字符 pre-exists 在 s2
本地数组的部分中,您的函数未明确设置。 (这是未定义的行为,实际上几乎可以显示任何内容;如果 cout
调用试图读取它没有所需访问权限的内存,程序也可能崩溃)。
要更正此问题,只需将 nul
(零或 '[=21=]'
)字符添加到 truncate
函数中的字符串末尾即可。假设您没有超出数组的边界,您可以使用循环索引的“剩余”值 i
来访问所需的元素;但是,为此,您需要声明 for
循环范围的 int i
外部 :
void truncate(char* s1, char* s2, int n)
{
int i; // Must be declared outside the FOR loop ...
for (i = 0; i < n; i++) {
s2[i] = s1[i];
}
s2[i] = '[=10=]'; // ... so we can use it here.
}
注意:另一种方法(但显然被你的老师禁止)是将 main
中 s2
数组的所有元素设置为零,before 调用你的 truncate
函数:
char s2[10] = ""; // Set ALL elements to zero
一些编译器(似乎包括您使用的在线编译器)会“隐式”将未初始化的局部数组的元素设置为零;但是永远不要依赖这个:它不是 C++ 标准的一部分并且编译器不需要强制执行此类行为。
#include <iostream>
using namespace std;
void truncate(char* s1, char* s2, int n) {
for (int i = 0; i < n; i++) {
s2[i] = s1[i];
}
}
int main() {
char s1[15] = "Hello World";
char s2[10];
int n{ 5 };
truncate(s1, s2, n);
cout << s2; // this should display: Hello
}
当我在 Visual Studio 中 运行 时,我得到这个输出:
Hello╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠Hello World
但是当我运行它使用在线编译器(在线GDB)时,输出是正常的:
Hello
我知道它与 [=14=]
终止符有关,但我就是想不通。
您的 truncate
函数不会将 所需的 nul
terminator character 添加到目标 (s2
) 字符串。因此,当您在 main
中调用 cout
时,它将继续打印字符,直到它在 garbage-initialized 数据之后的某个未指定位置找到预期的 nul
(零)字符 pre-exists 在 s2
本地数组的部分中,您的函数未明确设置。 (这是未定义的行为,实际上几乎可以显示任何内容;如果 cout
调用试图读取它没有所需访问权限的内存,程序也可能崩溃)。
要更正此问题,只需将 nul
(零或 '[=21=]'
)字符添加到 truncate
函数中的字符串末尾即可。假设您没有超出数组的边界,您可以使用循环索引的“剩余”值 i
来访问所需的元素;但是,为此,您需要声明 for
循环范围的 int i
外部 :
void truncate(char* s1, char* s2, int n)
{
int i; // Must be declared outside the FOR loop ...
for (i = 0; i < n; i++) {
s2[i] = s1[i];
}
s2[i] = '[=10=]'; // ... so we can use it here.
}
注意:另一种方法(但显然被你的老师禁止)是将 main
中 s2
数组的所有元素设置为零,before 调用你的 truncate
函数:
char s2[10] = ""; // Set ALL elements to zero
一些编译器(似乎包括您使用的在线编译器)会“隐式”将未初始化的局部数组的元素设置为零;但是永远不要依赖这个:它不是 C++ 标准的一部分并且编译器不需要强制执行此类行为。