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

Следующее не работает с ошибкой 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» и т. Д.


person Yana D. Nugraha    schedule 24.09.2009    source источник
comment
ошибка компилятора да .. Я забыл, что это за ошибка, но это разумно.   -  person Yana D. Nugraha    schedule 24.09.2009
comment
У вас есть ответы получше, но вы можете заставить второй пример работать следующим образом: char d [2] = {'d', 0}; или просто char d [2] = d; По сути, вам нужен 0 для завершения строки в стиле c, которую вы передаете для добавления   -  person sbk    schedule 24.09.2009
comment
Хорошая документация здесь: sgi.com/tech/stl/basic_string.html   -  person Martin York    schedule 24.09.2009


Ответы (13)


y += d;

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

person AraK    schedule 24.09.2009
comment
почему вы считаете + = лучше, чем push_back? Просто меньше набирать текст или у вас есть другая причина? - person Glen; 24.09.2009
comment
Меньше набора текста. В gcc basic_string::operator+= - это просто вызов в push_back. - person eduffy; 24.09.2009
comment
Это более естественный ИМО для струнных. push_back - это контейнерная функция, а строка - это специализированная функция в STL :) - person AraK; 24.09.2009
comment
Давайте перейдем к этому вопросу: почему вы считаете push_back лучше, чем + =? На мой взгляд, + = ясно и лаконично. - person Jesper; 24.09.2009
comment
@ Джеспер, я не знаю. Мне просто интересно, знал ли Арак что-то, чего не знал я. - person Glen; 24.09.2009
comment
Вы должны быть осторожны с этим, потому что, если вы приобретете привычку, это будет хорошо скомпилировано, если y будет char* вместо std::string. Он добавит d символа к указателю y. - person Zan Lynx; 15.03.2011

Используйте 1_:

std::string y("Hello worl");
y.push_back('d')
std::cout << y;
person Ferdinand Beyer    schedule 24.09.2009

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

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

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

s.append(1, d);

нет

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

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

s += d;
person Patrice Bernassola    schedule 24.09.2009
comment
Я думаю, что использование sizeof здесь семантически неверно (даже если это работает, поскольку sizeof (char) всегда один). Метод добавления естественно более полезен, если вы хотите добавить больше копий одного и того же символа !!!!!!!!!! - person UncleBens; 24.09.2009
comment
Почему вы используете sizeof(char) вместо 1? Вы хотите добавить ровно одно повторение d, так что просто скажите это. Использование sizeof здесь вводит в заблуждение, поскольку предполагает, что нужно указать append размер в байтах используемого типа данных (что не так). - person Ferdinand Beyer; 24.09.2009
comment
Как сказал Unclebens, метод добавления действительно более полезен при многократном добавлении одного и того же символа. - person Patrice Bernassola; 24.09.2009
comment
append () бесполезен для добавления одного символа, который требуется оператором. - person Johannes Overmann; 20.01.2021

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

std::string s = "hell";
s += std::string(1, 'o');
person Brian R. Bondy    schedule 24.09.2009
comment
Это не быстрее и не лучше, чем += или push_back(). - person Johannes Overmann; 20.01.2021

Я проверяю несколько предложений, запуская их в большой цикл. Я использовал 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'

Заключение

+= кажется более понятным, но если вас не интересует скорость, используйте добавление

person Hugo Zevetel    schedule 28.06.2016
comment
Чтобы такой ответ был осмысленным, вы должны хотя бы сказать, какой компилятор вы используете, потому что такие вещи могут сильно отличаться. Рассказ о вашем процессоре тоже может быть полезным, чтобы получить приблизительную оценку фактического воздействия, которое это может иметь. - person akaltar; 16.08.2016
comment
Я использовал Visual Studio 2015. Я буду искать gcc для других тестов. Мой процессор i7, 8 hearts, 2.20 Ghz .... Но каким бы ни был мой процессор, он не повлияет на реализацию std :: string ... за исключением случаев, когда некоторые из этих методов являются многопоточными, а некоторые - нет. - person Hugo Zevetel; 01.09.2016
comment
Иногда это оказывает влияние, особенно если вы показываете время в миллисекундах. Вместо этого вы можете показать в процентах относительно самого быстрого метода (так что фактическая скорость процессора не имеет значения). Также переместите эти данные из комментария в свой ответ, это просто общий этикет StackExchange. В противном случае хороший ответ. - person akaltar; 01.09.2016

Попробуйте использовать оператор + = текст ссылки, метод append () текст ссылки или метод push_back () текст ссылки

Ссылки в этом посте также содержат примеры использования соответствующих API.

person Michael Berg    schedule 24.09.2009

проблема с:

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

в том, что вам нужно иметь 'd', а не использовать имя char, например char d = 'd'; Или я не прав?

person Alex Spencer    schedule 25.06.2012
comment
Я просто попробовал, и все заработало. У меня char c = 'd', и я могу сделать y.push_back(c) без проблем. Так что проблем с std::string::push_back() нет (за исключением того, что он длиннее +=). - person Franklin Yu; 31.01.2020

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

person Mooing Duck    schedule 11.06.2013

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

person 2ndless    schedule 04.03.2014
comment
Это опасно, поскольку одиночный char не является строкой и не имеет нулевого конца. Это вызывает неопределенное поведение. - person Simon Kraemer; 26.02.2016
comment
Это просто неправильно. *d означает указатель отмены ссылки d, что является синтаксической ошибкой, поскольку d не является указателем. - person Franklin Yu; 31.01.2020

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

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
person Gopesh Bharadwaj    schedule 29.05.2020

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

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

person Ioan Stef    schedule 11.06.2013

Я нашел простой способ ... Мне нужно было прикрепить 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());

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

person Charles H    schedule 13.09.2018

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

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