2

I'm trying to concatenate strings using +, but there is some weird stuff going on. Here is my "Grade" class I have for a class project:

#pragma once #include <fstream> #include <iostream> #include <string> #include <vector> using namespace std; class Grade { private: string className; string student; string letter; public: Grade(string c, string s, string l) : className(c), student(s), letter(l) {} string getLetterGrade() const { return letter; } string getClassName() const { return className; } string getStudent() const { return student; } void setLetterGrade(string l) { letter = l; return;} void setClassName(string c) { className = c; return;} void setStudnet(string s) { student = s; return;} string toString() const { string output = "hello"+student; return output; } }; 

Obviously, the toString() method isn't currently what I want it to be. If I run the toString() as above, I get "hello529173860" out, as expected. However, if I change the line to:

string toString() const { string output = student+"hello"; return output; } 

then the output is "hello3860". This isn't just putting the hello string on the front, but its replacing characters from the student string in the process... somehow?

Furthermore, if I try to use:

string toString() const { string output = "hello"+" world"; return output; } 

I get an error:

Grade.h: In member function ‘std::string Grade::toString() const’: Grade.h:29:53: error: invalid operands of types ‘const char [6]’ and ‘const char [7]’ to binary ‘operator+’ string toString() const { string output = "hello"+" world"; return output; } ^ 

I'm really at a loss for what it going on here... especially since I have done string concatenation earlier in the program without issue. What I would like is to output something like:

"student+[some white space]+letter+[some white space]+className"

8
  • 1
    Welcome to one of the symptoms of using "using namespace std". Don't confuse a C-String (a simple string-literay, an array of characters, e.g. "hello") with a std::string. When you write "hello" + "world" you are actually trying to add two char arrays or two char* pointers. That said, the main problem is not the string operator +, it's somewhere else in your code. See ideone.com/wKrmu6 Commented Jan 14, 2014 at 4:07
  • Can you show us how you are using Grade objects? Commented Jan 14, 2014 at 4:07
  • I'm only in my second term of Com Sci, but if I was going to concatenate strings, I would try using a stringstream. I can't remember exactly, but I think that my instructor said something about how strings in C++ can't be correctly concatenated with just the "+" operator. Check out cplusplus.com/reference/sstream/stringstream/?kw=stringstream for a reference. Commented Jan 14, 2014 at 4:14
  • @zsherman Why do you need stringstream? What's wrong with std::string(const_char_one) + std::string(const_char_two) or strcat if you're using C-style strings? Concating an std::string with a const char* will Do The Right Thing, but "hello" + "world" will not. Commented Jan 14, 2014 at 4:16
  • @remyabel like I said, I am a newbie programmer, so this is the first I've heard of either of those options. After googling strcat though, I'd agree that it looks much more effective. Commented Jan 14, 2014 at 4:18

3 Answers 3

8

A std::string can be added to anything (another std::string, double-quoted string literal, char) and provide intuitive results, but if you try to add a double-quoted string literal to another string literal or a char then it won't "work":

  • a string literal added to a char or other integral value will undergo Standard Conversion to a const char*, then any number added to the pointer will move along the literal that number of characters: if the offset isn't inside the string literal then you get undefined behaviour if you dereference (use) the resultant pointer,

  • two string literals just can't be added, even after decaying to two pointers, so you'll get a compile-time error.

Sometimes you will want to explicitly construct a std::string so that concatenation with other values works as you'd like: e.g. my_string = std::string("hello ") + my_const_char_ptr + '\n'.

Examples:

std::string s = "Hello"; s + " World"; // ok "Hello " + s; // ok "Hello " + "World"; // NOT ok - two string literals s += " World"; // ok s += " Goodbye " + "World"; // NOT ok - "+" evaluated before "+=" s += std::string(" Goodbye ") + "World"; // OK - right-hand-side no longer two literals // BUT may be slower than two "s +=" 
Sign up to request clarification or add additional context in comments.

3 Comments

Everything you've said is true, but it doesn't explain how student+"hello" and "hello"+student could act as if student were truncated for one of them. For that matter I don't know if there's any rational explanation given the code in the question.
@MarkRansom: that "truncation" is not possible given the code currently in the question, but I do explain how adding a number to a string literal can give you a pointer somewhere inside the text - that's probably what happened in some earlier version of the code....
I eventually found out what the problem was. I was getting some information from a file, which had a '\r' character in it. Nonetheless, this answer was the most helpful in tracking down the problem, so I'm marking it as the accepted answer.
0

The constant strings "hello" and "world" are nothing but compile time constants of type const char*. Just like you cannot add two int pointers:

int *p1, *p2; p1+p1; // Error 

You cannot add two (const) char* objects. This is against the C/C++ language rules. If you must concatenate two const-char-pointers, you can just place them together:

"hello" "world" 

This technique is mainly useful if you use them along with macros. For example:

// Over simplified #define ONE(_x) _x #define TWO(_x) _X ONE("This is") TWO(" concatenation") 

If you are adding two (or more) runtime C-Strings, you must use strXXX functions (like strcat), or better use std::string.

4 Comments

For C++ at least, ""hello" and "world" are nothing but compile time constants of type const char*" - actually, their type is const char[5] and const char[6] respectively, not const char*. There is a Standard Conversion to const char * that will be attempted if a match is not found without.
True that, but when two arrays are added, they get boiled down to pointer-addition notion, not much of difference.
"when two arrays get added" never happens, and if it were made legal and given some semantics by the Standard, there's no particular reason to think the Standard Conversion to pointer would be involved, but I know what you mean... ;-).
I am not debating here. But VC compiler gives c2110 for int arr[1]; arr+arr; ;)
0

There is no operator + for character arrays. So it is obvious that this code

string toString() const { string output = "hello"+" world"; return output; } 

is invalid.

In this expression "hello"+" world" there are used two string literals that have the types correspondingly const char[6] and const char[7]. The operator + is not defined for arrays.

You could just write

string toString() const { return string( "hello" ) + " world"; } 

In this case there is used the operator + overloaded for the class std::string. Declaration of the local variable input is redundant. So you could simplify the function even the following way

string toString() const { return "hello world"; } 

2 Comments

This is only a semi-useful answer. Could you expand your answer by possibly explain an alternative way to do what OP is trying to accomplish?
@zsherman It is a very good answer. No any "alternative ways" are required for valid constructions.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.