0

I am using stringstream for converting string of numerals to an integer. I don't know why followed code isn't working. Can someone explain to me why I am always getting equal values of the tmp variable?

#include <fstream>
#include <string>
#include <sstream>
#include <cctype>

int main() {
    std::ifstream input("input.txt");
    std::ofstream output("output.txt");
    std::string str = "", line;
    std::stringstream ss;
    int tmp;
    while (std::getline(input, line)) {
        for (int i = 0, l = line.size(); i < l; i++) {
            if (isdigit(line[i]))
                str += line[i];
        }
        ss << str;
        // gets int from stringstream
        ss >> tmp;
        output << str << ' ' << tmp << std::endl;
        str = "";
        // stringstream clearing
        ss.str("");

    }

    return 0;
}
  • possible duplicate of [resetting a stringstream](http://stackoverflow.com/questions/7623650/resetting-a-stringstream) – inetknght Feb 09 '15 at 22:04
  • @inetknght with ss.clear() it works. But why? – Nikita Shelimov Feb 09 '15 at 22:07
  • 1
    [Don't use while(!input.eof())](http://stackoverflow.com/questions/5605125/why-is-iostreameof-inside-a-loop-condition-considered-wrong). Instead, change the loop to `while (std::getline(input, line)) {` – M.M Feb 09 '15 at 22:08
  • 2
    @NikitaShelimov `clear()` resets the position indicator and any error flags – M.M Feb 09 '15 at 22:09

3 Answers3

2

After

ss >> tmp;

ss is at EOF. None of the reads after that work. You can add a line

ss.clear();

after

ss.str("");

to clear its internal state. It will start to work. I used an if statement to test the hypothesis.

#include <iostream>
#include <fstream>
#include <string>
#include <sstream>
#include <cctype>

int main() {
    std::ifstream input("input.txt");
    std::string str = "", line;
    std::stringstream ss;
    int tmp;
    while (std::getline(input, line)) {
        for (int i = 0, l = line.size(); i < l; i++) {
            if (isdigit(line[i]))
                str += line[i];
        }
        ss << str;
        // gets int from stringstream
        ss >> tmp;
        std::cout << str << ' ' << tmp << std::endl;
        str = "";
        // stringstream clearing

        if (ss.eof())
        {
           std::cout << "ss is at eof\n";
        }

        ss.str("");
        ss.clear();

    }

    return 0;
}
R Sahu
  • 196,807
  • 13
  • 136
  • 247
1

To reset the std::stringstream you must first set the contents of the buffer with std::basic_stringstream::str and then reset the input position with std::basic_istream::seekg, giving

ss.str(str);
ss.seekg(0);
ss >> tmp;
Olaf Dietsche
  • 66,104
  • 6
  • 91
  • 177
0

As an alternative to your approach on having to clear the stringstream at each iterate as @R Sahu mentioned, you can declare std::stringstream ss inside the while loop. This way, you destroy the variable at the end of each iterate and create a new one each time the while loop is executed.

#include <fstream>
#include <string>
#include <sstream>
#include <cctype>

int main()
{
    std::ifstream input("input.txt");
    std::ofstream output("output.txt");
    std::string line;

    while (std::getline(input, line))
    {
        std::string str;
        std::stringstream ss;
        int tmp;

        for (int i = 0; i < line.size(); i++)
        {
            if (isdigit(line[i]))
                str += line[i];
        }
        ss << str;
        // gets int from stringstream
        ss >> tmp;
        output << str << " " << tmp << std::endl;
    }

    return 0;
}
namu
  • 195
  • 1
  • 7