Як додати знак до рядка 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.