复制/截断字符数组中的奇怪符号


#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

但当我使用在线编译器(online GDB(运行它时,输出是正常的:

Hello

我知道这与终止符有关,但我就是想不通。

您的truncate函数不会将必需的nul终止符添加到目标(s2(字符串中。因此,当您在main中调用cout时,它将继续打印字符,直到它在某个未指定的位置找到预期的nul(零(字符,该位置位于s2本地数组中未由函数显式设置的部分中预先存在的垃圾初始化数据之后。(这是未定义的行为,几乎任何东西都可以实际显示;如果cout调用试图读取它没有所需访问权限的内存,程序也可能崩溃(。

要更正此问题,只需将nul(零或''(字符添加到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] = ''; // ... so we can use it here.
}

注意:另一种方法(但显然被老师禁止(是将mains2数组的所有元素设置为零,然后调用truncate函数:

char s2[10] = ""; // Set ALL elements to zero

一些编译器(似乎包括你使用的在线编译器(会";隐含地";将未初始化的本地数组的元素设置为零;但是永远不要依赖这个:它不是C++标准的一部分,编译器不需要来强制执行这种行为。

最新更新