【问题标题】:Why won't these strings concatenate in C++?为什么这些字符串不会在 C++ 中连接?
【发布时间】:2015-02-06 01:10:45
【问题描述】:

我有一个我用 C++ 编写的两个测试程序的例子。第一个工作正常,第一个错误。请帮我解释一下这里发生了什么。

#include <iostream>
#include <string>
#include <stdint.h>
#include <stdlib.h>
#include <fstream>
using namespace std;

string randomStrGen(int length) {
static string charset = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890";
string result;
result.resize(length);
for (int32_t i = 0; i < length; i++)
    result[i] = charset[rand() % charset.length()];
return result;
}

int main()
{
ofstream pConf;
pConf.open("test.txt");
pConf << "rpcuser=user\nrpcpassword=" 
     + randomStrGen(15)
     + "\nrpcport=14632"
     + "\nrpcallowip=127.0.0.1"
     + "\nport=14631"
     + "\ndaemon=1"
     + "\nserver=1"
     + "\naddnode=107.170.59.196";
pConf.close();
return 0;
}

它打开'test.txt'并写入数据,没问题。但是,这不会:

#include <iostream>
#include <string>
#include <stdint.h>
#include <stdlib.h>
#include <fstream>
using namespace std;

string randomStrGen(int length) {
static string charset = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890";
string result;
result.resize(length);
for (int32_t i = 0; i < length; i++)
    result[i] = charset[rand() % charset.length()];
return result;
}

int main()
{
ofstream pConf;
pConf.open("test.txt");
pConf << "rpcuser=user\n"
     + "rpcpassword=" 
     + randomStrGen(15)
     + "\nrpcport=14632"
     + "\nrpcallowip=127.0.0.1"
     + "\nport=14631"
     + "\ndaemon=1"
     + "\nserver=1"
     + "\naddnode=107.170.59.196";
pConf.close();
return 0;
}

第二个程序的唯一区别是'rpcpassword'被移到了下一行。

matthew@matthew-Satellite-P845:~/Desktop$ g++ test.cpp 
test.cpp: In function ‘int main()’:
test.cpp:23:6: error: invalid operands of types ‘const char [14]’ and ‘const char [13]’ to binary ‘operator+’ 
  + "rpcpassword="

【问题讨论】:

  • 不同之处在于std::stringoperator+ 重载以与const char* 连接。
  • Aasmund 的回答是正确的,但顺便说一下,相邻的字符串文字会在相当早的阶段被编译器连接起来(例如,“abc”“def”变成“abcdef”,即使它们位于不同的行中来源)。所以,如果你删除除randomStrGen(15) 之前和之后的所有'+',它不仅会正确编译,而且会使用更少的内存并运行得更快。
  • FWIW - 使用串联的示例 here...

标签: c++ string char string-concatenation


【解决方案1】:

C++ 中的字符串文字 ("foo") 不是 string 类型的;它属于const char[x] 类型,其中x 是字符串文字的长度加1。字符数组不能与+ 连接。但是,字符数组可以string 连接,结果是string,它可以进一步与字符数组连接。因此,"a" + functionThatReturnsString() + "b" 有效,但 "a" + "b" 无效。 (请记住,+ 是左关联的;它首先应用于最左边的两个操作数,然后应用于结果和第三个操作数,依此类推。)

【讨论】:

  • OP 应该只删除 + 因为两个连续的字符串文字会自动连接。
  • @user2676680 有很多non-member overloads for operator+ 有一个const char* 和一个std::string。但是,没有内置的operator+ 需要两个const char*s。
  • @user2676680 最后两句话解释了为什么第一句话有效
  • 如果@remyabel 的评论中没有明确这一点:它们在程序的翻译过程中被连接起来,因此它也具有零运行时开销。如果您没有文字,您可以将您的 + 替换为 &lt;&lt; 但在您当前的情况下效率会降低。
【解决方案2】:

"rpcuser=user\nrpcpassword=" + randomStrGen(15) + "\nrpcport=14632"("rpcuser=user\nrpcpassword=" + randomStrGen(15)) + "\nrpcport=14632" 这样的群组。在这里,+ 始终与类类型的参数一起使用,因此在重载解析后会得到 std::string::operator+

"rpcuser=user\n" + "rpcpassword=" + randomStrGen(15)("rpcuser=user\n" + "rpcpassword=") + randomStrGen(15) 这样的群组。在这种情况下,第一个 + 用于两个非类类型,因此它没有重载,并且语言没有为两个 const char [] 值定义 +。 (我来自旧 C,所以我有点不只是将它们添加为 char *s 并在运行时给你一个不错的 SIGSEGV。)

【讨论】:

  • 两个答案都非常有帮助,您的括号分组使其点击。我不喜欢它在我不知道的情况下超载的事实,这似乎会导致程序员不知道到底发生了什么。我会确保改变我对字符串文字的使用。
  • 我应该用括号来让我的观点更清楚,所以这也得到了我的支持 :-) (只要你使用 C++,你最好习惯于重载...... )
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-02-25
  • 2010-10-07
  • 2011-08-09
  • 1970-01-01
相关资源
最近更新 更多