lark
lark

Reputation: 31

string will not cout first part

I'm writing a game in c++ and i want it to output a string character by character and slow down the out put with the Sleep() function. The string is :

string output = "It is Super Effective!" + '\n';  

when I try cout << output it returns "r Effective" with no new line
the code for the display function is

void textDisplay(string s){
    s = " " + s;
    for (int i = 0; i < s.size(); i++){
        char c = s[i];
        cout << c;
        Sleep(20);
    }
}

Upvotes: 3

Views: 129

Answers (3)

Ben Voigt
Ben Voigt

Reputation: 283624

When the C++ compiler encounters an operator in your program, it performs overload resolution, just like for overloaded functions. Binary operator+ has many overloads, but you care about these two:

std::string operator+(std::string, char)   // string concatenation

const char* operator+(const char*, std::ptrdiff_t)     // pointer arithmetic

Other answers have explained what these two alternate meanings of + are, I will show you how the compiler determines that the second meaning is better.

Your actual parameters have type const char[N] and char. The first argument can implicitly convert to const char* using array-to-pointer decay, and to std::string, by using array-to-pointer decay followed by a "user-defined conversion" (std::string's implicit constructor). The second argument can convert to any other integral type, including std::ptrdiff_t, via an implicit widening.

All the different types of conversions are ranked according to a table in the C++ Standard, and in this table, user-defined conversions are used only as a last resort. So the pointer arithmetic interpretation wins.

Upvotes: 3

paxdiablo
paxdiablo

Reputation: 881153

It's because "It is Super Effective!" + '\n' is being interpreted as the pointer to the C-string plus the integral value of the character \n, which is 10 in ASCII. This is happening before the assignment to the C++-string.

You'll see, if you count ten characters in from the start of your C-string, you do indeed end up at the r.

So here's what's happening, in detail and sequence:

  • The expression "It is Super Effective!" is being interpreted as a char pointer to the initial I character (a C-string).
  • You're then adding ten (the integral value of \n) to that to get a pointer to the r (still a C-string).
  • That C-string "r Effective!" is then being used to construct the C++-string.

In graphical form:

base +  0: | I  | -------+
base +  1: | t  |        |
base +  2: |    |        |
base +  3: | i  |        |
base +  4: | s  |        |
base +  5: |    |     Add ten
base +  6: | S  |        |
base +  7: | u  |        |
base +  8: | p  |        |
base +  9: | e  |        |
base + 10: | r  | <------+
base + 11: |    |
base + 12: | E  |
  :
base + 21: | !  |
base + 22: | \0 |

You can change it to add the character to the C++ string rather than the C string:

string output = "It is Super Effective!";
output += '\n';

but I'm not entirely certain why you wouldn't just do:

string output = "It is Super Effective!\n";

One other thing you may want to watch out for. It's possible that the flushing of characters to standard output will only occur when a newline is sent, meaning that you'll seem to get the entire string in one hit, some seven minutes or so after you expected the first character to appear.

If that happens, remember to flush the stream after every character:

cout << c << flush;

Upvotes: 9

jxh
jxh

Reputation: 70382

In this context, the + is not joining the character to the string literal, but is returning a pointer value offset by \n bytes. In ASCII, this would be 0x0A, or 10. This is because the string literal is an array of const char, which then decays to the address of its first element. The + operator then offsets 10 characters past that element.

                     1
 0 1 2 3 4 5 6 7 8 9 0
|I|t| |i|s| |S|u|p|e|r| |E|f|f|e|c|t|i|v|e|!|

You can correct this by initializing the string first, and then appending.

string output = "It is Super Effective!";
output += '\n';

Or, you can use string literal concatenation, by dropping the + and using "\n" instead:

string output = "It is Super Effective!" "\n";  

Or just make the whole thing a string, which would be most clear.

string output = "It is Super Effective!\n";  

Upvotes: 3

Related Questions