Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

do...while() repeating the last string twice

The following code splits the provided string/line down to the characters. Why does the loop repeats that last string twice? How to fix it?

#include <iostream>
#include <vector>
#include <sstream>
#include <string>

using namespace std;

int main()
{
    string main, sub;
    cout << "Enter string: ";
    getline(cin, main);
    istringstream iss(main);
    do
    {
        iss >> sub;
        cout << sub << endl;
        vector<char> v(sub.begin(), sub.end());
        for(int i = 0; i < v.size(); i++)
         {
             cout << v[i] << endl;
         }
    } while (iss);
    return 0;
}

Input:

hello world

Desired output

hello
h
e
l
l
o
world
w
o
r
l
d

Actual output:

hello
h
e
l
l
o
world
w
o
r
l
d
world
w
o
r
l
d

I have removed elements which are unrelated to the problem as much as possible

like image 474
Bot666 Avatar asked Feb 15 '16 18:02

Bot666


2 Answers

In the last run, the iss raises a failure so the value of sub is not updated which causes the repeat to happen. One way to see this is to set sub to be the empty string at the start of the do loop. To avoid this kind of issue, I would do something like the following

while(iss>>sub){
  cout<<sub<<endl;
  etc
}

Also, I would like to point out that you can iterate through a string as it can be treated as a char*, so you do not need the vector conversion stuff.

like image 72
Untitled123 Avatar answered Oct 24 '22 07:10

Untitled123


The problem is that the conversion to bool of a istream only returns false if the failbit or badbit is set, but not if the stream is empty. The failbit is for example set set after you try to extract a string from an empty istream. That is why your loop runs one times more: When the istream is empty the failbit is not set, only after no string could be extracted in the extra iteration the fails bit is set and the loop terminates. A solution could be to use:

#include <iostream>
#include <vector>
#include <sstream>
#include <string>

using namespace std;

int main()
{
    string main, sub;
    cout << "Enter string: ";
    getline(cin, main);
    istringstream iss(main);
    while(iss >> sub)
    {
        cout << sub << endl;
        vector<char> v(sub.begin(), sub.end());
        for(int i = 0; i < v.size(); i++)
         {
             cout << v[i] << endl;
         }
    }
    return 0;
}
like image 30
Haatschii Avatar answered Oct 24 '22 08:10

Haatschii