Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Reversing input, output string is unexpectedly empty

Tags:

c++

string

#include <iostream>
#include <string>
using namespace std;
int main()
{
  string s1;
  cin>>s1;

  int n=s1.size();
  string s2;
  for(int a=0;a<n;a++)
  {
    s2[a]=s1[n-1-a];        
  }
  cout<<s2;
}

However I am not getting any output, But I can print elements of reversed string. Can anybody please help.

like image 752
kp' Avatar asked Dec 10 '22 06:12

kp'


1 Answers

string s2; // no size allocated
for(int a=0;a<n;a++)
{
    s2[a]=s1[n-1-a]; // write to somewhere in s2 that doesn't exist yet

You are writing into elements of s2 that you never created. This is Undefined Behaviour, and anything may happen, including appearing to work normally. In this case, you are probably overwriting some random place in memory. It might crash, or that memory might really exist but not break anything else right away. You might even be able to read that back later, but it would only seem to work by pure accident.

You could catch this problem by always using s2.at(a) to access the data, as it will do a range check for you. ([] does not do a range check). There's a cost to this of course, and sometimes people will skip it in circumstances where they are certain the index cannot be out of bounds. That's debateable. In this case, even though you were probably sure you got the maths right, it still would have helped catch this bug.


You need to either create that space up front, i.e. by creating a string full of the right number of dummy values, or create the space for each element on demand with push_back. I'd probably go with the first option:

string s2(s1.size(), '\0'); // fill with the right number of NULs
for(int a=0;a<n;a++)
{
    s2.at(a)=s1.at(n-1-a); // overwrite the NULs

You might want to choose a printable dummy character that doesn't appear in your test data, for example '#', since then it becomes very visible when you print it out if you have failed to correctly overwrite some element. E.g. if you try to reverse "abc" but when you print it out you get "cb#" it would be obvious you have some off-by-one error.


The second option is a bit more expensive since it might have to do several allocations and copies as the string grows, but here's how it would look:

string s2; // no space allocated yet
for(int a=0;a<n;a++)
{
    s2.push_back(s1.at(n-1-a)); // create space on demand

I assume you are doing this as a learning exercise, but I would recommend against writing your own reverse, since the language provides it in the library.

like image 199
BoBTFish Avatar answered Dec 12 '22 19:12

BoBTFish