如何将一个字符添加到std::string中?

242

以下代码出错并提示:prog.cpp:5:13: error: invalid conversion from ‘char’ to ‘const char*’

int main()
{
  char d = 'd';
  std::string y("Hello worl");
  y.append(d); // Line 5 - this fails
  std::cout << y;
  return 0;
}

我也尝试了以下代码,虽然编译通过,但在运行时表现不稳定:

int main()
{
  char d[1] = { 'd' };
  std::string y("Hello worl");
  y.append(d);
  std::cout << y;
  return 0;
}

非常抱歉问这个愚蠢的问题,但我已经在谷歌上搜索过了,只看到了"char数组转char指针"、"char指针转char数组"等内容。


1
编译器出错了,是的,我忘记了具体是哪个错误,但这很正常。 - Yana D. Nugraha
4
以下有更好的答案,但您可以通过以下方式使第二个示例正常工作:char d[2] = {'d',0};或者只需使用char d[2] = "d"。基本上,您需要一个0来终止传递给append的C风格字符串。 - sbk
这里有很好的文档:http://www.sgi.com/tech/stl/basic_string.html - Martin York
15个回答

296
y += d;

我会使用+=运算符而不是命名函数。


2
你为什么认为 += 比 push_back 更好?只是因为少打几个字吗,还是有其他原因? - Glen
5
更少的输入。在 gcc 中,basic_string::operator+= 只是对 push_back 的调用。 - eduffy
3
在我看来,对于字符串而言使用push_back更为自然。push_back是容器函数,在STL中,字符串是一种专门的容器 :) - Khaled Alshaya
9
让我们把问题转过来:为什么您认为push_back比+=更好?在我看来,+=清晰简洁。 - Jesper
48
如果你养成这个习惯,就需要小心处理。如果 ychar* 而不是 std::string,那么这段代码仍然可以编译通过,但会给指针 y 添加 d 个字符。请注意避免此类情况。 - Zan Lynx
显示剩余2条评论

96

使用push_back()

std::string y("Hello worl");
y.push_back('d')
std::cout << y;

24
使用append方法向std::string变量添加字符,需要使用以下重载方式:

使用append方法向std::string变量添加字符,需要使用以下重载方式:

std::string::append(size_type _Count, char _Ch)

编辑:您是正确的,我误解了上下文帮助中显示的size_type参数。这是要添加的字符数。因此,正确的调用是:

s.append(1, d);

不是

s.append(sizeof(char), d);

或者最简单的方法:

s += d;

我认为在这里使用sizeof不是语义上正确的(即使它恰好能工作,因为sizeof(char)始终为1)。如果您想要附加更多相同字符的副本,则append方法自然更有用! - UncleBens
1
为什么要使用sizeof(char)而不是1?你想要附加一个重复的d,所以只需要这么说。在此处使用sizeof是误导性的,因为它暗示着必须告诉append所使用的数据类型的字节大小(事实并非如此)。 - Ferdinand Beyer
正如Unclebens所说,当需要多次添加相同的字符时,使用append方法更加实用。 - Patrice Bernassola
append() 不适用于添加单个字符,这正是 OP 所要求的。 - Johannes Overmann

13

除了其他提到的方法之外,还有一个字符串构造函数可以接受一个字符和该字符重复的次数,所以你可以使用它来追加单个字符。

std::string s = "hell";
s += std::string(1, 'o');

这种方法既不比 +=push_back() 更快,也没有其他任何优势。 - Johannes Overmann

11

我通过在一个大循环中运行它们来测试几个命题。 我使用微软Visual Studio 2015作为编译器,我的处理器是i7,8Hz,2GHz。

    long start = clock();
    int a = 0;
    //100000000
    std::string ret;
    for (int i = 0; i < 60000000; i++)
    {
        ret.append(1, ' ');
        //ret += ' ';
        //ret.push_back(' ');
        //ret.insert(ret.end(), 1, ' ');
        //ret.resize(ret.size() + 1, ' ');
    }
    long stop = clock();
    long test = stop - start;
    return 0;

根据这个测试,结果如下:

     operation             time(ms)            note
------------------------------------------------------------------------
append                     66015
+=                         67328      1.02 time slower than 'append'
resize                     83867      1.27 time slower than 'append'
push_back & insert         90000      more than 1.36 time slower than 'append'

结论

+= 看起来更易理解,但如果您关心速度,请使用 append


为了使这样的答案有意义,您至少应该告诉我们您正在使用哪个编译器,因为这些东西可能会有很大的差异。同时,介绍一下您的处理器也是很好的,以便对实际影响进行粗略估计。 - akaltar
我使用的是Visual Studio 2015。我将寻找GCC来进行其他测试。我的处理器是i7,8个核心,2.20 GHz...但无论我的处理器如何,它都不会对std::string实现产生影响...除非其中一些方法是多线程的,而其他方法则不是。 - Gregoire Cattan
有时候它会产生影响,特别是当你展示以毫秒为单位的时间。相反,你可以展示相对于最快方法的百分比(因此实际处理器速度无关紧要)。另外,将这些数据从评论中移动到你的答案中,这是 StackExchange 的通用礼仪。除此之外,回答很好。 - akaltar

6

3

以下是与之相关的问题:

std::string y("Hello worl");
y.push_back('d')
std::cout << y;

这是因为您必须使用“d”而不是像char d = 'd'这样使用字符名称。或者我错了吗?


我刚试了一下,它运行得很好。我有 char c = 'd',并且我可以毫无问题地执行 y.push_back(c)。因此,std::string::push_back() 没有问题(除了比 += 更长)。 - Franklin Yu

2
int main()
{
  char d = 'd';
  std::string y("Hello worl");

  y += d;
  y.push_back(d);
  y.append(1, d); //appending the character 1 time
  y.insert(y.end(), 1, d); //appending the character 1 time
  y.resize(y.size()+1, d); //appending the character 1 time
  y += std::string(1, d); //appending the character 1 time
}

请注意,在所有这些示例中,您都可以直接使用字符字面量:y += 'd';
由于与无关原因,您的第二个示例几乎可以工作。 char d [1] = {'d'}; 没有起作用,但是 char d [2] = {'d'};(请注意数组大小为两个)将大致与 const char* d = "d"; 相同,并且字符串字面值可以附加:y.append(d);

2
此外还需要添加插入选项,因为尚未提及。
std::string str("Hello World");
char ch;

str.push_back(ch);  //ch is the character to be added
OR
str.append(sizeof(ch),ch);
OR
str.insert(str.length(),sizeof(ch),ch) //not mentioned above

1
尝试使用d作为指针 y.append(* d)

2
这很危险,因为单个的 char 不是字符串,也没有空终止符。这样做会导致未定义的行为。 - Simon Kraemer
1
这是错误的。*d 表示对指针 d 进行解引用,但由于 d 不是指针,因此会出现语法错误。 - Franklin Yu

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接