iwrestledthebeartwice
iwrestledthebeartwice

Reputation: 734

why cout is not printing this string?

So, I'm new to C++ and I can't figure why this is happening. I have a string with all the alphabets and I copied 10 characters from it into a new string s2, character by character using a for loop as follows and when I execute it the cout function is printing a blank line.

#include <iostream>

using namespace std;

int main(){
    string s = "abcdefghijklmnopqrstuvwxyz";
    string s2;
    for(int i=0; i<10; i++){
        s2[i] = s[i];
    }
    cout << s2 << endl;
    return 0;
}

But when I print this string s2 character by character I got the correct output

#include <iostream>

using namespace std;

int main(){
    string s = "abcdefghijklmnopqrstuvwxyz";
    string s2;
    for(int i=0; i<10; i++){
        s2[i] = s[i];
    }
    
    for(int i=0; i<10; i++){
        cout << s2[i];
    }
    return 0;
}

Any help would be appreciated!

Upvotes: 5

Views: 1444

Answers (3)

UweJ
UweJ

Reputation: 489

One might be confused, because

for(int i=0; i<10; i++){
    cout << s2[i];
}

delivers the correct output. The std::string is a class with functions and overloaded operators. The []-operator of the std::string shows a similar behaviour as a char-array. The "array-elements" are defined with this code snipped:

for(int i=0; i<10; i++){
        s2[i] = s[i];
    }

If the code of the question is executed several times, the undefined behaviour of this snipped can be seen.

If you try to use a string iterator you will see, that the string s2 is still an empty string.

string::iterator si;
    for (si=s2.begin(); si!=s2.end(); si++)
    {
        cout << *si ;
    }

Upvotes: 3

songyuanyao
songyuanyao

Reputation: 172924

Both your code have undefined behavior. string s2; just initializes s2 as an empty std::string which contains no elements. Trying to access element as s2[i] leads to UB, means anything is possible. (Even it appears to give the correct output in your 2nd code snippet.)

You can use push_back to append element as

for(int i=0; i<10; i++){
    s2.push_back(s[i]);
}

Or

for(int i=0; i<10; i++){
    s2 += s[i];
}

Or you can make s2 containing 10 elements in advance.

string s2(10, '\0'); // or... string s2; s2.resize(10);
for(int i=0; i<10; i++){
    s2[i] = s[i];
}

Upvotes: 11

Thomas Sablik
Thomas Sablik

Reputation: 16452

An empty string s2 is created. s2[i] = s[i]; won't resize the string but it causes undefined behavior. One way to solve the problem is to append each character. This will change the size and can involve multiple memory allocations.

Another way is to create a string with correct size or reserve memory with:

  1. Create "empty" string with size 10:

     string s2(10, '\0');
     for(int i=0; i<10; i++){
         s2[i] = s[i];
     }
    
  2. Reserve memory

     string s2;
     s2.reserve(10);
     for(int i=0; i<10; i++){
         s2 += s[i];
     }
    
  3. Initialize the string with a substring

     string s2 = s.substr(0, 10);
    

    or

     string s2(s.begin(), s.begin() + 10);
    

    or

     string s2(s, 0, 10);
    

Upvotes: 4

Related Questions