Як додати знак до рядка std ::?


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, який ви
передаєте

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

Відповіді:


225
y += d;

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


2
чому ти вважаєш + = кращим, ніж push_back? Це просто менше набирати текст чи у вас є інша причина?
Глен

4
Це менше набирати текст. В gcc, basic_string::operator+=це просто дзвінок в push_back.
eduffy

2
Більш природний ІМО для струн. push_back - це функція контейнера, а рядок - спеціалізований для STL :)
AraK

6
Давайте повернемо це питання: чому ви вважаєте, що push_back кращий за + =? На мою думку, + = зрозуміло і стисло.
Jesper

34
Ви хочете бути обережними з цим, тому що якщо ви ввійдете в звичку, це складеться чудово, якщо yце char*замість std::string. Це додасть dсимволи до покажчика y.
Зан Лінкс


19

Щоб додати char до std :: string var за допомогою методу додавання, вам потрібно використовувати це перевантаження:

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

Редагувати: Ви праві, я неправильно зрозумів параметр size_type, відображений у довідці про контекст. Це кількість символів, які потрібно додати. Тож правильний дзвінок

s.append(1, d);

ні

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

Або найпростіший спосіб:

s += d;

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

1
Для чого ви використовуєте sizeof(char)замість 1? Ви хочете додати саме одне повторення d, тому просто скажіть це. Використання sizeofтут вводить в оману, оскільки це говорить про те, що потрібно вказати appendрозмір байтів використовуваного типу даних (що не так).
Фердинанд Бейєр

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

10

Окрім інших згаданих, один із конструкторів струн приймає знак char та кількість повторень для цього char. Таким чином, ви можете використовувати це, щоб додати одну таблицю.

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

7

Я тестую кілька пропозицій, запускаючи їх у великий цикл. Я використовував microsoft 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'

Висновок

+= здається більш зрозумілим, але якщо ви заперечуєте про швидкість, використовуйте додавання


Щоб така відповідь була значущою, вам слід хоча б сказати, який компілятор ви використовуєте, оскільки такі речі можуть бути різними ЛОТ. Розповідь про ваш процесор також може бути чудовим, щоб отримати приблизну оцінку щодо реального впливу, який це може мати.
акалтар

Я використовував візуальну студію 2015. Я буду шукати gcc, щоб зробити якісь інші тести. Мій процесор i7, 8 сердець, 2,20 ГГц .... Але що б не мій процесор, це не матиме впливу на std :: string string ... за винятком випадків, коли деякі з цих методів є багатопоточними, а інші - ні.
Гюго Зеветель

Іноді це має вплив, особливо якщо ви показуєте таймінги в мілісекундах. Натомість ви можете показати у відсотках відносно найшвидшого методу (Тому фактична швидкість процесора не має значення) Також перемістіть ці дані з коментаря до вашої відповіді, це просто загальний етикет StackExchange. Інакше приємна відповідь.
акалтар


2

проблема з:

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

це те, що ви повинні мати "d" на відміну від використання імені char, наприклад 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;і встановив нову рядок, що дорівнює символу, "list" - 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
оператор + = (char c); перевантажений для струн. Насправді конструктор рядків не приймає жодного символу, див. Відповідь Брайана;)
AraK
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.