Amit Upadhyay Amit Upadhyay - 3 months ago 11
C++ Question

std::string returning inappropriate value

I wrote a program which perform string compression using counts of repeated characters. The program in C++ is :

#include<iostream>
#include<cstring>
std::string compressBad(std::string str)
{
std::string mystr = "";
int count = 1;
char last = str[0];
for (int i = 0; i < str.length();++i)
{
if(str[i] == last)
count++;
else
{
std::string lastS = last+"";
std::string countS = std::to_string(count);
mystr.append(lastS);
mystr.append(countS);
//mystr = mystr + last + count;
count = 1;
last = str[i];
}
}
std::string lastS = last+"";
std::string countS = std::to_string(count);
mystr.append(lastS);
mystr.append(countS);
return mystr;
//return mystr+last+count;
}
int main()
{
std::string str;
std::getline(std::cin, str);
std::string str2 = compressBad(str);
std::cout<<str2;
/*if (str.length() < str2.length())
std::cout<<str;
else
std::cout<<str2;*/
std::cout<<std::endl;
return 0;
}


Few example on running this are :

Input : sssaaddddd

Output : ùÿÿ*425

Output it should print : s3a2d5


Second example:

Input : sssaaddd

Output: ùÿÿ*423

Output it should print : s3a2d3


I also implemented the same concept in Java and there it is working fine. The java implementation is here

Why is this problem happening with above code.

Answer

There may be other issues in your code, but I think that this line might be to blame:

std::string lastS = last+"";

Here, you're trying to convert the character last to a string by concatenating the empty string to the end. Unfortunately, in C++ this is interpreted to mean "take the numeric value of the character last, then add that to a pointer that points to the empty string, producing a new pointer to a character." This pointer points into random memory, hence the garbage you're seeing. (Notice that this is quite different from how Java works!)

Try changing this line to read

std::string lastS(1, last);

This will initialize lastS to be a string consisting of just the character stored in last.

Another option would be to use an ostringstream:

std::ostringstream myStr;
myStr << last << count;

// ...

return myStr.str();

This eliminates all the calls to .append() and std::to_string and is probably a lot easier to read.