1

Sorry for the noob question, I'm a newbie programmer and transitioning from C to C++. I could easily write a program to reverse a string in C the same way with minor changes but writing this in C++, why does this not print anything:

#include <iostream>
#include <string>

using namespace std;

int main(){
    string s,p;
    getline(cin,s);
    int j=0,i = 0;
    while(s[i]!='\0'){
        i++;
    }
    i--;
    while(i!=-1){
        p[j] = s[i];
        j++;
        i--;
    }
    cout << p << endl;
    return 0;
}

if i replace the p with say p[2], it correctly prints out the reverse 3rd character of the original string, but i cant find a way to print the whole string.

4 Answers4

3
    std::string str{"reverse me"};
    std::string rev{str.rbegin(), str.rend()};
    //or when you are not interested in the orignal string
    std::reverse(str.begin(), str.end());

Giving the constructur of the reverse string the reversed iterators of your input string gives you the string in reversed order.

Thrasher
  • 138
  • 10
2

To fix your string reverse code you just have to resize the string object p:


int main(){
    std::string s = "hello",
           p;
    p.resize(s.size()); // this was causing your problems, p thought it was size 0

    for (int i = s.size() - 1, j = 0; i >= 0; i--, j++)
    {
        p[j] = s[i];
    }

    std::cout << p << std::endl;
    return 0;
}

In addition to this, there is no need to find \0 in the string, while it will be there, you can just ask std::string what its size() is.

On a side note, while std::string probably allocates some memory by default, just assuming it has enough to store whatever you input is going to be undefined behaviour.

nick
  • 449
  • 3
  • 12
  • 1
    "*while it will probably be there*": It is required to be there since C++11. "*probably allocates some memory by default*": Typically `std::string` implementations don't allocate by default and instead use short string optimization until the string becomes too long. In any case, even if the capacity was large enough, accessing outside the string's size is UB. – walnut Mar 25 '20 at 06:53
  • Thanks @walnut I updated the answer accordingly. I was not entirely sure how to interpret the `string` documentation when it said a default constructed string had "zero size and unspecified capacity", so thanks for clarifying that :) – nick Mar 25 '20 at 06:59
1

While there are ways to iterate over a std::string and fill the contents of another, the overload of std::basic_string::operator= will replace the content of p (if any) with the content of s in a simple assignment. See std::basic_string::operator=

For example:

#include <iostream>
#include <string>

int main (void) {

    std::string s {}, p {};

    std::cout << "enter string: ";
    if (getline (std::cin, s)) {
        p = s;  /* simple assignment replaced content of p with content of s */
        std::cout << "string in p : " << p << '\n';
    }
}

Example Use/Output

$ ./bin/stringps
enter string: the string s
string in p : the string s
David C. Rankin
  • 81,885
  • 6
  • 58
  • 85
0

string p; doesn't have enough allocated space for directly accessing by something like p[j]

You can change to initialize p from copying s like below, your code will work.

string s;
getline(cin,s);
string p(s);  // p will be allocated and be the same as s
CodingLab
  • 1,441
  • 2
  • 13
  • 37