我对C ++中的字符串连接有疑问。
string str = "ab" + 'c';
cout << str << endl;
char ch = 'c';
string str1 = "ab";
string str2 = str1 + ch;
cout << str2 << endl;
代码产生:
ed before SaveGraphicsState
abc
有人可以解释这一行的处理:string str = "ab" + 'c';
?
答案 0 :(得分:8)
你对第一行的看法是正确的,这正是发生的事情。
对于像+
这样的文字字符串,没有任何默认的"ab"
运算符,所以会发生什么是编译器接受(作为C风格的字符串)并使用const char*
指针指向文字。然后它会使用您的文字字符'c'
并将其提升为int
并带有一些值。然后将此int添加到文字的地址并用作C字符串。由于您已经超出了为文字字符串分配的空间,因此结果是未定义的,它只是从结果地址中打印出字符,直到找到空值。
如果您想一次性创建字符串,可以帮助编译器首先确定您想要使用强制转换string
转换为std::string str = std::string("ab") + 'c';
。或者(如单独的注释中所示)使用串联来执行此操作,这可能会或可能不会更好地执行。使用您的案例中更清晰的一个:std::string str = "ab"; str += 'c';
。
在第二种情况下,您已经创建了string
,并且string
有一个超载的operator+
,可以进行直观的连接。
答案 1 :(得分:2)
string str = "ab" + 'c';
字符串文字不能像那样连接。 "ab"
是一个字符数组,它会衰减为指针(在此上下文中),并且您正在添加'c'
,它是指针的一个整数。所以指针前进了'c'
的ascii值。
也就是说,上面的代码等同于:
char char * s= "ab";
string str = &s['c']; //the ascii value of 'c' acts like an index to the array.
我确信这不是你想要的。实际上,它调用未定义的行为,因为&s['c']
引用的内存区域可能不在进程的地址空间中。
你真正想要做的简短形式(即连接)是:
string str = string("ab") + "c";
答案 2 :(得分:2)
您的猜测是正确的,除了字符串文字不在堆栈上,它位于内存中特定于工具链的位置,通常位于只读部分。
答案 3 :(得分:1)
运算符重载仅适用于至少有一个重载运算符参数是用户定义类型(即类实例)的情况,因此+运算符不能重载以添加字符串和字符。并做一些明智的事情。充其量,你将获得指针运算 - 几乎肯定不是你想要的。通常的工作方式是显式转换:
string s = string( "foo" ) + "bar"; // s will contain "foobar"
答案 4 :(得分:1)
"ab"
是C字符串。
'c'
是角色。
尝试:
string str = string("ab") + "c";
如果你想让它变得更简单,总会有:
string str = "ab";
str += 'c';
或者,您可以使用std::stringstream
:
stringstream ss;
ss << "ab" << 'c';
答案 5 :(得分:0)
"ab"
是const char *
。 'c'
是char
。我的猜测是'c'
被转换为整数,所述整数被添加到"ab"
的地址,结果指针被传递给std::string
的构造函数。你很幸运,它不会惨不忍睹。
有关如何正确连接的详细信息,请参阅其他答案。
答案 6 :(得分:0)
我认为string str = "ab" + 'c';
的作用类似于:
string tmp = stirng("ab"); // implicit conversion
tmp = tmp + 'c'; // uses overloaded + operator
str = tmp;
答案 7 :(得分:0)
这是构建到C ++中的:
#include <iostream>
#include <string>
int main()
{
std::string s("Stand back! I've got jimmies!" "DDD");
std::cout << "Stand back! I've got jimmies!" "DDD";
}
输出:
Stand back! I've got jimmies!DDD