C ++ std :: string :: find всегда возвращает npos? - PullRequest
0 голосов
/ 24 февраля 2012

Я пытаюсь заставить эту функцию разрезать строку, а затем вернуть ее без пробелов и всех строчных. И для этого я пытаюсь найти " ", чтобы увидеть, содержит ли строка "The Time Traveller (for so it will be convenient to speak of him)" пробел.

Код выглядит следующим образом, передавая строку выше этой функции. Всегда возвращает string::npos. Есть идеи по поводу проблемы?

string chopstring(string tocut){
    string totoken = ""; 
    int start = 0;
    while(tocut[0] == ' ' || tocut[0] == 10 || tocut[0 == 13]){
        tocut.erase(0);
    }
    int finish = 0;
    finish = tocut.find(" ", start);
    if (finish == string::npos){
        cout << "NPOS!" << endl;
    }
    for (int i = start; i < finish; i++){
        totoken += tocut[i];
    }
    tocut.erase(start, finish);
    return tokenize(totoken);
}

Ответы [ 2 ]

3 голосов
/ 24 февраля 2012

tocut.erase(0) стирает все из tocut. Аргументом является первый символ, который нужно удалить, а длина по умолчанию - «все».

tocut[0 == 13] должно быть tocut[0] == 13. Это очень разные заявления. Также, пожалуйста, сравните со значениями символов ('\t') вместо целых чисел. Между прочим, это в сочетании с предыдущей является вашей реальной проблемой: tocut[0 == 13] становится tocut[false], то есть tocut[0], то есть true. Таким образом, цикл продолжается до тех пор, пока tocut не станет пустым, что является немедленным (так как вы стираете все это слишком усердно с первого раза).

Чистый эффект двух вышеупомянутых ошибок заключается в том, что при достижении оператора find, tocut является пустой строкой, которая не содержит пробела. Идем дальше ...

Вы можете использовать функцию substr вместо цикла для перехода с tocut на totoken.

Ваша последняя строка tocut.erase(start, finish) ничего не делает полезной, поскольку tocut был передан по значению, и вы сразу же вернетесь после этого.

1 голос
/ 24 февраля 2012

На самом деле, большая часть кода может быть написана намного проще (при условии, что я понимаю, что вы хотите удалить все пробелы правильно):

string chopstring(string tocut) {
    std::string::size_type first(tocut.find_first_of(" \n\r"));
    if (first != tocut.npos) {
        tocut.substr(first);
    }
    tocut.erase(std::remove(tocut.begin(), tocut.end(), ' '), tocut.end());
    return tokenize(tocut);
}

Если вы действительно хотите удалить все пробелы, вы, вероятно,хотите использовать std::remove_if() с подходящим предикатом.

...