john smith
john smith

Reputation: 649

What is wrong with this string assignment?

string s="abcdefghijklmnopqrstuvwxyz"
char f[]=" " (s.substr(s.length()-10,9)).c_str() " ";

I want to get the last 9 characters of s and add " " to the beginning and the end of the substring, and store it as a char[]. I don't understand why this doesn't work even though char f[]=" " "a" " " does.

Is (s.substr(s.length()-10,9)).c_str() not a string literal?

Upvotes: 1

Views: 191

Answers (3)

voltrevo
voltrevo

Reputation: 10459

First, consider whether you should be using cstrings. In C++, generally, use string.

However, if you want to use cstrings, the concatenation of "abc" "123" -> "abc123" is a preprocessor operation and so cannot be used with string::c_str(). Instead, the easiest way is to construct a new string and take the .c_str() of that:

string s="abcdefghijklmnopqrstuvwxyz"
char f[]= (string(" ") + s.substr(s.length()-10,9) + " ").c_str();

(EDIT: You know what, on second thought, that's a really bad idea. The cstring should be deallocated after the end of this statement, so using f can cause a segfault. Just don't use cstrings unless you're prepared to mess with strcpy and all that ugly stuff. Seriously.)

If you want to use strings instead, consider something like the following:

#include <sstream>
...
string s="abcdefghijklmnopqrstuvwxyz"
stringstream tmp;
tmp << " " << s.substr(s.length()-10,9) << " ";
string f = tmp.str();

Upvotes: 3

Daniel N&#228;slund
Daniel N&#228;slund

Reputation: 2420

@Xeo tells you how to solve your problem. Here's some complimentary background on how string literals are handled in the compilation process.

From section A.12 Preprocessing of The C Programming language:

Escape sequences in character constants and string literals (Pars. A.2.5.2, A.2.6) are replaced by their equivalents; then adjacent string literals are concatenated.

It's the Preprocessor, not the compiler, who's responsible for the concatenation. (You asked for a C++ answer. I expect that C++ treats string literals the same way as C). The preprocessor has only a limited knowledge of the C/C++ language; the (s.substr(s.length()-10,9)).c_str() part is not evaluated at the preprocessor stage.

Upvotes: 1

Xeo
Xeo

Reputation: 131907

No, it's not a string literal. String literals always have the form "<content>" or expand to that (macros, like __FILE__ for example).

Just use another std::string instead of char[].

std::string f = " " + s.substr(s.size()-10, 9) + " ";

Upvotes: 5

Related Questions