Функция не возвращает желаемую строку - PullRequest
0 голосов
/ 27 сентября 2018
#include <iostream>
#include <string>

using namespace std;
string wordB(string input);

int main() {
    //ask for word
    cout << "Enter a word\n";

    //get word
    string input = "";
    cin >> input;

    //return with b in between all letters
    cout << wordB(input);
    cout << endl << input;
}

string wordB(string str) {
    string rString = "";

    for (unsigned i = 0; i < str.length(); ++i) {
        rString += "B" + str.at(i);
    }
    cout << endl << rString;

    return rString;
}

Попытка отобразить слово, которое вводят пользователи, где между каждым символом есть буква "B".Когда я запускаю это со словом "join", я получаю обратно "trtr".

Ответы [ 4 ]

0 голосов
/ 27 сентября 2018

То, что вы видите, является результатом order of evaluation.

Оператор += заставит вычислять правую часть выражения и результатбудет добавлен к строке.

Это то, что вызывает проблему, с которой вы сталкиваетесь, потому что правая сторона не std::string, и, следовательно, значение оператора + в этом rhs просто переводитуказатель на арифметику, а не на конкатенацию строк, как и следовало ожидать.

Простое исправление должно быть более явным и сделать это:

rString = rString + "B" + str.at(i);

Теперь компилятор сначала оценивает правильнуюсторона оператора = в виде строки, и вы получите конкатенацию.Это также дает дополнительное преимущество, позволяя компилятору сообщать вам, если правая часть не является строкой.


Другой альтернативой является использование потоков строк.Я думаю, что это выглядит чище, поэтому вот оно:

#include <sstream>
...

string wordB(string str) {
    std::ostringstream oss;

    for (unsigned i = 0; i < str.length(); ++i) {
        oss << 'B' << str.at(i);
    }
    cout << endl << oss.str();

    return oss.str();
}
0 голосов
/ 27 сентября 2018

По общему признанию, это ловушка ... в этой строке

rString += "B" + str.at(i);

часть "B" + str.at(i) не выполняет то, что можно ожидать: она добавляет str.at(i) к указателю char (указывая напервая буква "Б").Исправить несложно:

rString += std::string("B") + str.at(i);
                        //  ^-------------- now calls the correct operator

Так же, как любопытство, подумайте об этом:

(rString += "B") += str.at(i);

Я не рекомендую писать это (оно слишком запутано), но оно делает правильные вещи,потому что есть std::string::operator+(char*) и std::string::operator+(char).

0 голосов
/ 27 сентября 2018

Особенно приятное исправление, доступное начиная с C ++ 14, заключается в написании

rString += "B"s + str.at(i);

, отмечая s, который является определяемым пользователем литералом .Это затем заставляет использовать перегруженный оператор + на std::string вместо встроенного +, который фактически выполняет сомнительную (и потенциально неопределенную) арифметику указателя на const char[2]буквальный "B" распался до const char*.

0 голосов
/ 27 сентября 2018

"B" + str.at(i); не делает то, о чем вы думаете;это не цепочка строк.Он говорит: возьмите указатель char*, указывающий на начало строкового литерала "B", увеличьте его на количество символов, равное коду ASCII символа str.at(i), и обработайте полученный указатель как указывающий на ноль.завершенная строка.Если str.at(i) не окажется '\x0' или '\x1' (маловероятно), ваша программа будет иметь неопределенное поведение.

Есть много разных способов сделать то, что вы хотите.Вот один из них:

rString.push_back('B');
rString.push_back(str[i]);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...