#include <iostream>
#include <cstring>
using namespace std;
int main ()
{
char str1[10] = "Hello";
char str2[10] = "World";
int len ;
strcat( str1, str2);
len = strlen(str1);
cout << len << endl<<str1<<endl;
return 0;
}
当我像这样char str1[5]="hello";
初始化str1时,C ++编译器给我一个错误(意味着字符串的大小必须比给定的字符串多1)。
但是在strcat
中,我们将str1
连接到str2
,第一个字符串的大小为10,字符串的长度也为10(表示没有额外的空字符)。为什么这种变化的行为?
我们是否在strcat
函数中使用C字符串转换C ++字符串,请解释。
答案 0 :(得分:2)
我们是否正在转换c ++字符串
不,您的程序中没有c ++字符串(即std::string
)。
为什么这会改变行为?
你写了一个不同的程序,行为是不同的。
在第一种情况下,您的程序格式不正确。该标准要求编译器在编译时通知您。并且编译器也很容易检测到您的错误。变量的类型是“5个字符的数组”。 6个字符不适合 - 类型错误。类型在编译时是已知的。
在示例代码中,您使用strcat
。如果你看一下this reference,你会发现
如果目标数组不足以容纳src和dest的内容以及终止空字符,则行为未定义。
Standard不要求编译器警告您未定义的行为。实际上,编译器通常很难证明程序具有未定义的行为 - 即使在这种特殊情况下它似乎很明显。
strcat
的参数是指针。您将正确类型的指针传递给strcat
。没有类型错误。错误的值是错误的。这些值在运行时被复制到数组中(除非优化器有一些魔力)。要弄清楚你的错误,编译器必须模拟程序的执行。对所有代码路径执行此操作将非常缓慢。因此,编译器将责任留给程序员以满足strcat
。
答案 1 :(得分:0)
这些是C风格的字符串,而不是C ++字符串,即您没有使用std :: string类。 C风格的字符串由&#39; \ 0&#39;终止,这意味着您需要超出字符串长度的额外存储位置。 &#34;你好&#34;长度为5,但您需要一个大小为6的数组来存储它。在您的示例中,实际上不必指定数组的大小,只需执行以下操作并让编译器计算大小:
char str1[] = "Hello";
strcat函数要求第一个参数指向一个具有足够空间用于连接字符串的数组。这是一个危险的函数,因为它不会检查是否实际情况,如果不是,它将简单地覆盖超出数组末尾的任何内容。在您的情况下,连接两个长度为5个字符的字符串,您将获得一个长度为10个字符的字符串,并且您需要确保第一个参数指向一个长度至少为11个字符的数组。如果你使用C ++字符串,你不必担心这些:
#include <string>
#include <iostream>
int main()
{
std::string str1("Hello");
std::string str2("World");
str1.append(str2);
std::cout << str1.size() << '\n' << str1 << std::endl;
}