White space insertion in std::stringstream fails - c++

I'm trying to insert white space in std::stringstream in this way.
std::stringstream sstr;
sstr.str("");
sstr << " ";
sstr << 10;
and then setting it as a label like that
label->setString(sstr.str().c_str());
but it's only giving me 10, space is not included. I've followed many links to solve problem but of no use. Following link suggests to use getline() but in my case I cannot do that :
stringstream doesn't accept white space?
I've also tried to use std::noskipws but it also not work :
sstr << std::noskipws << " ";
Any help will be appreciated.

std::stringstream should not remove your whitespace when used like this. Are you sure that it is not the label-object that is trimming your string and removing the whitespace?
Try debugging or printing out your string before setting it to the label.

You can use put method to append a single char:
std::stringstream sstr;
sstr.str("");
sstr.put(' ');
sstr.put(10);

I think you're using it wrong:
string labelstr;
std::stringstream sstr;
sstr.str("");
sstr << " ";
sstr << 10;
ss >> noskipws >> labelstr;
label->setString(labelstr);
http://www.cplusplus.com/reference/ios/noskipws/

Your code works as expected for me. Here's a runnable example: http://cpp.sh/8d6.
The culprit must be setString trimming your input. Or possibly some other function that reads the string later.

Related

C++ Stringstream only picking up first string

I have a text file with a series two strings delimited by a colon on each line.
I'm using getline to grab the entire line then string stream to split the two strings and put them onto a vector. The code works fine on the first pass it grabs the strings perfectly. Then after that on the 2nd pass of the while loop and so forth it doesn't grab the new input. The string stream seems to leave the original first values for some reason.
if (infile.is_open()) {
std::stringstream ss;
std::string current_line;
std::string tempProxy;
std::string tempPort;
while (std::getline(infile, current_line)) {
ss << current_line;
std::getline(ss, tempProxy, ':');
std::getline(ss, tempPort);
std::cout << tempProxy << " and " << tempPort << std::endl;
}
Any idea why it doesn't want to grab the strings from current_line on any pass except the first iteration?
You're reusing ss but not resetting it correctly. When you extract the second word from the first line, the stream is exhausted and put in an 'EOF' state. When streams are in this or any other 'error' state they don't do anything. You have to clear the error before you can continue to use them.
If you were to check for errors returned by operator<< and getline in the loop (or if you were to cause ss to throw exceptions on errors*) you would find they are indicating that they are not successful past the first iteration. It's a good general practice to always check for errors, and especially so when you're debugging.
You can clear the error by changing your loop:
while (std::getline(infile, current_line)) {
ss.clear(); // clears the error, not the contents
ss << current_line;
However doing this means that ss will accumulate all the lines in its internal buffer. The code will produce your expected output unless the file is large and you run out of memory or something like that.
You can see the accumulating internal buffer with the following:
while (std::getline(infile, current_line)) {
ss.clear();
ss << current_line;
std::cout << "ss internal buffer: " << ss.str();
Instead of using the formatted input to add ss you are probably better off using the .str() member to set it, which will replace the previous data instead of adding to it.
while (std::getline(infile, current_line)) {
ss.clear();
ss.str(current_line);
Alternatively you can construct a new stringstream in each iteration of the loop. This does ensure that no error states or data are carried over from previous iterations. It may also be slower, but you'll have to profile that for yourself.
while (std::getline(infile, current_line)) {
std::stringstream ss(current_line);
* Exceptions are nice because you don't need to remember to check them... except in cases like this where they're not enabled by default. Also I've noticed some C++ implementations have bugs in their iostreams exception code because people don't use it much.
I think you're looking for something like:
if (infile.is_open()) {
std::stringstream ss;
std::string current_line;
std::string tempProxy;
std::string tempPort;
while (std::getline(infile, current_line)) {
std::stringstream to_split;
to_split.str(current_line);
std::getline(to_split, tempProxy, ':');
std::getline(to_split, tempPort);
std::cout << tempProxy << " and " << tempPort << std::endl;
}

Split string with space but only get first word

I'm having problem to split the string with space as a delim. I have tried 2 of the proposed solution as in here:
Split a string in C++?
(using copy + istringstream and split method)
However, no matter what I did, the vector only get the first word (not the rest). When I use the split method, it's working with anything else (dot, comma, semi colon...) but not space.
Here is my current code, can you tell me what I get wrong? Or how I should try to approach the fix?
int main()
{
std::vector<std::string> textVector;
std::string textString;
std::cout << "Input command : ";
std::cin >> textString;
std::istringstream iss(textString);
std::copy(std::istream_iterator<std::string>(iss), std::istream_iterator<std::string>(), std::back_inserter(textVector));
for (int i = 0 ; i < textVector.size(); i++) {
std::cout << textVector[i];
}
return 0;
}
The runnable code: http://cpp.sh/8nzq
Reason is simple, std::cin >> textString only reads until first whitespace. So textString only contains the first word.
To read entire line, you should instead use: std::getline(std::cin, textString);

std::stringstream only supports one input at a time?

Since std::stringstream is a stzream, and according to the documention here, you can perform any operation a stream supports.
So I expected the following sample to work, but it seems it doesn't. I'm using MingW with gcc 4.8.3.
Variant A:
std::string s;
std::stringstream doc;
doc << "Test " << "String ";
doc << "AnotherString";
doc >> s;
std::cout << s << std::endl;
Variant B:
std::string s;
std::stringstream doc;
doc << "Test ";
doc << "AnotherString";
doc >> s;
std::cout << s << std::endl;
The output of this is only
Test
While I expected that it would concatenate the individual strings until I read from the stream back what I put there.
So what is the approperiate way to concatenate strings? Do I really have to read out each one individually and concatenate them manually, which seems quite awkward to me in C++.
It is putting each of the strings into doc, so that its content is:
Test String AnotherString
Then when you extract using doc >> s, it only reads up to the first whitespace. If you want to get the entire stream as a string, you can call str:
std::cout << doc.str() << std::endl;
It will only read one word till a white-space by using stream >> s. Besides #JosephMansfield's answer of using str(), alternatively you can use getline() (works perfectly if you the string doesn't contains new lines):
getline(doc, s);

Getting the remainder of a stringstream c++

I have a stringstream where I need to get the first part out and then get the remainder into a separate string. For example I have the string "This is a car" and I need to end up with 2 strings: a = "This" and b = "is a car".
When I use stringstream to get the first part using <<,then I use the .str() to convert to a string which of course gave me the whole thing "This is a car". How can I get it to play how I want?
string str = "this is a car";
std::stringstream ss;
ss << str;
string a,b;
ss >> a;
getline(ss, b);
EDIT: correction thanks to #Cubbi:
ss >> a >> ws;
EDIT:
This solution can handle newlines in some cases (such as my test cases) but fails in others (such as #rubenvb's example), and I haven't found a clean way to fix it. I think #tacp's solution is better, more robust, and should be accepted.
You can do this: first get the whole string, then get the first word, using substr to get the rest.
stringstream s("This is a car");
string s1 = s.str();
string first;
string second;
s >> first;
second = s1.substr(first.length());
cout << "first part: " << first <<"\ second part: " << second <<endl;
Testing this in gcc 4.5.3 outputs:
first part: This
second part: is a car
You can do a getline on the stream after reading out the first bit....
Another way to do this is with rdbuf:
stringstream s("This is a car");
string first;
stringstream second;
s >> first;
second << s.rdbuf();
cout << "first part: " << first << " second part: " << second.str() << endl;
This may be a good option if you're ultimately going to output the result to a stream instead of a string.

how to get string from a line of strings?

I have following string:
"hw_core_detectionhook::Iocard const*"
I have to get only first part, i.e all text present before space, i.e I need the "hw_core_detectionhook::Iocard" part only.
std::stringstream ss;
ss << "hw_core_detectionhook::Iocard const*";
std::string s;
ss >> s;
std::cout << s;
Output:
hw_core_detectionhook::Iocard
See the complete demo online : http://www.ideone.com/w9l1C
s.substr(0,s.find_first_of(" "));