stringnpos
stringnpos

Reputation: 3

std::string.find_first_not_of, unexpected return value

#include <stdio.h>
#include <string>

int main(void)
{
    printf("%u\n", std::string("\n").find_first_not_of(" \t\n\v\f\r", 0, 1));
}

The following program prints 0, not std::string::npos as I expected. Why?

Upvotes: 0

Views: 2248

Answers (6)

Sylvain Defresne
Sylvain Defresne

Reputation: 44463

The method find_first_not_of interpret the last argument as the number of char to consider in its first argument, not in the string.

size_type std::string::find_first_not_of(
    const char* str, size_type index, size_type num) const;

The argument num is the number to consider in str, not in this ! So in your case, it only consider the first caracter of " \t\n\v\f\r". You code is equivalent to:

#include <cstdio>
#include <string>

int main(void)
{
    printf("%u\n", std::string("\n").find_first_not_of(" ", 0));
}

If you want to only match a substring of the std::string, I think you must call find_first_not_of on an explicit substring, that is:

#include <cstdio>
#include <string>

int main(void)
{
    printf("%u\n", std::string("\n").substr(0, 1).find_first_not_of(" \t\n\v\f\r"));
}

BTW, here is the description of the behavior of the find_first_not_of method:

The find_first_not_of() function either:

  • returns the index of the first character within the current string that does not match any character in str, beginning the search at index, string::npos if nothing is found,
  • searches the current string, beginning at index, for any character that does not match the first num characters in str, returning the index in the current string of the first character found that meets this criteria, otherwise returning string::npos,
  • or returns the index of the first occurrence of a character that does not match ch in the current string, starting the search at index, string::npos if nothing is found.

Upvotes: 0

Erik
Erik

Reputation: 91260

Your call matches:

size_t find_first_not_of ( const char* s, size_t pos, size_t n ) const;

n is the number of chars in s, and you're passing 1. So, you're searching for the first char that is not space. The rest of your " \t\n\v\f\r" string is ignored.

Likely you simply want:

find_first_not_of(" \t\n\v\f\r")

Upvotes: 5

fpointbin
fpointbin

Reputation: 1663

See it:

#include <stdio.h>
#include <string>

int main(void)
{
        std::string s("\n");
        if( s.find_first_not_of(" \t\n\v\f\r", 0, 1) != std::string::npos )
                    printf("%u\n", s.find_first_not_of(" \t\n\v\f\r", 0, 1));
        else
                puts("npos");
        return 0;
}

Upvotes: 0

Sarfaraz Nawaz
Sarfaraz Nawaz

Reputation: 361254

Based on what you want to print, I can say the third parameter should be the length of string you passed. So here is the corrected version:

#include <stdio.h>
#include <string>

int main(void)
{
    std::string s=" \t\n\v\f\r";
    printf("%u\n", std::string("\n").find_first_not_of(s.c_str(), 0, s.length()));

   //since now I'm using std::string, you can simply write:
   printf("%u\n", std::string("\n").find_first_not_of(s));
}

Demo at ideone : http://ideone.com/y5qCX

Upvotes: 0

Asha
Asha

Reputation: 11232

According to this, string::find_first_not_of searches for the first character in the object which is not part of either str, s or c, and returns its position. Since "\t" is such character, return value is 0.

Upvotes: 0

Ben Voigt
Ben Voigt

Reputation: 283614

The third parameter doesn't mean what you think it does.

Upvotes: 1

Related Questions