Как добавить символ в 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" и т. Д.

drowneath
источник
ошибка компилятора да .. Я забыл, что это за ошибка, но это разумно.
Утро
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
65

Используйте push_back():

std::string y("Hello worl");
y.push_back('d')
std::cout << y;
Фердинанд Бейер
источник
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)

2ndless
источник
Это опасно, так как сингл не 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, для строкового конструктора нет вызова. В противном случае он создаст строковый объект посредством приведения, затем он добавит символ в этой строке к другой строке. Слишком много проблем для крошечного персонажа;)

progician
источник
1
оператор + = (символ с); перегружен для строк. Фактически, строковый конструктор не принимает один символ, см. Ответ Брайана;)
AraK