samuraiseoul
samuraiseoul

Reputation: 2967

C++ std::string::find always returns npos?

I'm trying to get this function to cut up a string, and then return it without whitespace and all lowercase. And to do this I'm trying to find a " " to see if a string, "The Time Traveller (for so it will be convenient to speak of him)", contains a space.

The code is as follows, passing in the string above to this function. It always returns string::npos. Any idea about the problem?

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

Upvotes: 0

Views: 2850

Answers (2)

Dietmar K&#252;hl
Dietmar K&#252;hl

Reputation: 154015

Actually, the majority of the code could be written much simpler (assuming my understanding that you want to remove all spaces is correct):

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

If you actually want to remove all whitespace, you probably want to use std::remove_if() with a suitable predicate.

Upvotes: 1

Borealid
Borealid

Reputation: 98559

tocut.erase(0) is erasing all of tocut. The argument is the first character to erase, and the default length is "everything".

tocut[0 == 13] should probably be tocut[0] == 13. Those are very different statements. Also, please compare with character values ('\t') instead of integers. Incidentally, this in conjunction with the previous is your actual problem: tocut[0 == 13] becomes tocut[false], which is tocut[0], which is true. So the loop runs until tocut is empty, which is immediately (since you erase it all overzealously in the first go).

The net effect of the above two bugs is that when you reach the find statement, tocut is the empty string, which does not contain a space character. Moving on...

You can use the substr function instead of your loop to migrate from tocut to totoken.

Your last tocut.erase(start, finish) line isn't doing anything useful, since tocut was pass-by-value and you immediately return after that.

Upvotes: 3

Related Questions