Santosh Sahu
Santosh Sahu

Reputation: 2244

Using find_last_of with string-C++

I want to extract the last part of a given string. Below is the code snippet:

int main ()
{
   const std::string path="C:\Users\rd_nsl_Bentley_1.2.sc";
   auto const pos=path.find_last_of('\\');
   cout<<"pos="<<pos<<endl;
   const auto leaf=path.substr(pos+1);

   std::cout << leaf << '\n';
}

My output should be

leaf rd_nsl_Bentley_1.2.sc

But the output is

pos=18446744073709551615
C:Usersrd_nsl_Bentley_1.2.sc

The pos value is arbitary and only "\" is removed from the whole string.

Upvotes: 0

Views: 2775

Answers (2)

Remy Lebeau
Remy Lebeau

Reputation: 597051

You need to escape the \ characters in your string literal, just like you do for the character literal you are passing to find_last_of().

Change your string literal from this:

"C:\Users\rd_nsl_Bentley_1.2.sc"

To this:

"C:\\Users\\rd_nsl_Bentley_1.2.sc"

Or this, if you are using C++11 or later:

R"(C:\Users\rd_nsl_Bentley_1.2.sc)"

If you don't escape, the compiler will interpret \U and \r as escape sequences (where \U is invalid as it is not in \Unnnnnnnn format, and \r is a carriage return). They will not be interpreted as individual characters '\', 'U', '\', 'r' like you are expecting.

Thus, your string will not have any '\' characters for find_last_of() to find, so it will return std::string::npos, which is -1 (aka 18446744073709551615 when interpreted as an unsigned 64-bit number) so pos+1 would be 0, causing substr() to return the original string as-is, and std::cout would ignore the \U and \r escape sequences, producing the output you are seeing.

Upvotes: 2

m_callens
m_callens

Reputation: 6360

When you define your path variable, you aren't escaping the \ characters to properly add them to the string. It's treating the string like you've tried \U and \r as escaped characters.

Change to "C:\\Users\\rd_nsl_Bentley_1.2.sc"

Upvotes: 0

Related Questions