Как добавить символ в std :: string?


175

Следующее не удается с ошибкой 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;
}

Извините за этот тупой вопрос, но я искал в Google, что я мог видеть, это просто "char array to char ptr", "char ptr to char array" и т. Д.


ошибка компилятора да .. Я забыл, что это за ошибка, но это разумно.
Утро

3
Ниже у вас есть лучшие ответы, но вы можете сделать так, чтобы второй пример работал так: char d [2] = {'d', 0}; или просто char d [2] = "d"; По сути, вам нужен 0 для завершения строки в стиле c, которую вы передаете для добавления
sbk

Хорошая документация здесь: sgi.com/tech/stl/basic_string.html
Мартин Йорк,

Ответы:


225
y += d;

Я бы использовал +=оператор вместо именованных функций.


2
почему вы считаете + = лучше, чем push_back? Это просто меньше печатать или у вас есть другая причина?
Глен

4
Это меньше печатать. В gcc, basic_string::operator+=это просто вызов в push_back.
Эдуффи

2
Это более естественное ИМО для струн. push_back - это функция контейнера, а строка - специализированная функция в STL :)
AraK

6
Давайте перевернем этот вопрос: почему вы считаете push_back лучше, чем + =? На мой взгляд, + = ясно и сжато.
Джеспер

34
Вы хотите быть осторожным с этим , потому что если вы получаете в привычку, это будет компилировать только штраф , если yэто char*вместо std::string. Это добавит dсимволы к указателю y.
Zan Lynx


19

Чтобы добавить символ в переменную std :: string, используя метод append, вам нужно использовать эту перегрузку:

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

Изменить: Вы правы, я неправильно понял параметр size_type, отображаемый в контекстной справке. Это количество символов для добавления. Таким образом, правильный вызов

s.append(1, d);

не

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

Или самый простой способ:

s += d;

Я думаю, что использование sizeof не является семантически правильным (хотя это работает, так как sizeof (char) всегда один). Метод добавления, естественно, более полезен, если вы хотите добавить больше копий одного и того же символа !!!!!!!!!!
UncleBens

1
Почему вы используете sizeof(char)вместо 1? Вы хотите добавить ровно одно повторение d, так что просто скажите это. Использование sizeofздесь вводит в заблуждение, поскольку предполагает, что нужно указать appendразмер байта используемого типа данных (что не так).
Фердинанд Бейер

Как сказал Unclebens, метод добавления действительно более полезен при многократном добавлении одного и того же символа.
Патрис Бернассола

10

В дополнение к другим упоминается, один из строковых конструкторов принимает символ и количество повторений для этого символа. Таким образом, вы можете использовать это, чтобы добавить один символ.

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

7

Я проверил несколько предложений, запустив их в большой цикл. Я использовал Microsoft Visual Studio 2015 в качестве компилятора, и мой процессор i7, 8 Гц, 2 ГГц.

    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


Чтобы такой ответ имел смысл, вы должны хотя бы сказать, какой компилятор вы используете, потому что такие вещи могут сильно отличаться. Рассказ о вашем процессоре также может быть полезен, чтобы получить приблизительную оценку фактического влияния, которое это может оказать.
Акалтар

Я использовал Visual Studio 2015. Я буду искать gcc для проведения некоторых других тестов. Мой процессор i7, 8 червей, 2,20 ГГц .... Но какой бы ни был мой процессор, он не окажет влияния на реализацию std :: string ... за исключением случаев, когда некоторые из этих методов являются многопоточными, а некоторые нет.
Уго Зеветель

Иногда это оказывает влияние, особенно если вы показываете время в миллисекундах. Вместо этого вы можете показать в процентах относительно самого быстрого метода (поэтому фактическая скорость процессора не имеет значения). Переместите эти данные из комментария в ваш ответ, это всего лишь общий этикет StackExchange. В противном случае хороший ответ.
апреля


2

проблема с:

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()(кроме того, что это дольше, чем +=).
Франклин Ю.

1
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);.


1

Попробуйте использовать d в качестве указателя y.append (* d)


Это опасно, так как сингл не charявляется строкой и не имеет нулевого терминатора. Это вызывает неопределенное поведение.
Симон Крамер

Это просто неправильно. *dозначает указатель де-ссылки, dкоторый является синтаксической ошибкой, поскольку dне является указателем.
Франклин Ю.

0
str.append(10u,'d'); //appends character d 10 times

Обратите внимание, что я написал 10u, а не 10, сколько раз я хотел бы добавить символ; замените 10 на любое число.


0

Я нашел простой способ ... Мне нужно было привязать charк струне, которая строилась на лету. Мне нужно было, char list;потому что я предоставлял пользователю выбор и использовал этот выбор в switch()утверждении.

Я просто добавил еще одну std::string Slist;и установил новую строку равной символу «список» - a, b, c или тому, что конечный пользователь выбрал следующим образом:

char list;
std::string cmd, state[], Slist;
Slist = list; //set this string to the chosen char;
cmd = Slist + state[x] + "whatever";
system(cmd.c_str());

Сложность может быть крутой, но простота круче. по моему мнению


0

Также добавлена ​​опция вставки, как еще не упомянуто.

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

Если вы используете push_back, для строкового конструктора нет вызова. В противном случае он создаст строковый объект посредством приведения, затем он добавит символ в этой строке к другой строке. Слишком много проблем для крошечного персонажа;)


1
оператор + = (символ с); перегружен для строк. Фактически, строковый конструктор не принимает один символ, см. Ответ Брайана;)
AraK
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.