do...while() repeating the last string twice
Asked Answered
S

2

5

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

Suu answered 15/2, 2016 at 18:8 Comment(1)
A
7

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.

Aberdare answered 15/2, 2016 at 18:12 Comment(0)
A
3

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;
}
Arnettearney answered 15/2, 2016 at 18:12 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.