Thread: Stringstream runs into infinite loop

  1. #1
    [](){}(); manasij7479's Avatar
    Join Date
    Feb 2011
    Location
    *nullptr
    Posts
    2,657

    Exclamation Stringstream runs into infinite loop

    Code:
    //#include blah blah blah...
    using namespace std;
    class token
    {
        public:
        bool status;//0 for str & 1 for num
        string str;
        double num;
    } ;
    typedef vector<token> storage;
    
    int main()
    {
        string a;
        token t;
        storage s;
        double x;
        string y;
        getline(cin,a);
        istringstream st;
        st.str(a);
        while(!st.eof())
        {
            if(st>>x,x)
            {
                
                t.status=true;
                t.num=x;
                cout<<t.num<<'\n';
    
            }
            else
            {
                st>>y;
                t.status=false;
                t.str=y;
                cout<<t.str<<'\n';
    
            }
            //cout<<t.status;
            s.push_back(t);
        }
    
    }
    The number part executes nicely but whenever I put strings into the input....the while starts an infinite loop.
    btw_ this is for parsing the input for a calculator program...
    Any idea what is going wrong...or a better way to put the different parts of the input line to be analysed separately later?

  2. #2
    Programming Wraith GReaper's Avatar
    Join Date
    Apr 2009
    Location
    Greece
    Posts
    2,738
    No copy constructor or assignment operator... how do you expect push_back to work properly?
    Devoted my life to programming...

  3. #3
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    Quote Originally Posted by manasij7479
    whenever I put strings into the input....the while starts an infinite loop.
    The problem is that the stringstream enters a failed state when you attempt to read into x fails. You need to clear() the error state.

    By the way, do not use eof() to control the loop in this way. Rather, use something like:
    Code:
    for (;;)
    {
        if (st >> x)
        {
            t.status = true;
            t.num = x;
            cout << t.num << '\n';
        }
        else
        {
            st.clear();
            if (st >> y)
            {
                t.status = false;
                t.str = y;
                cout << t.str << '\n';
            }
            else
            {
                break;
            }
        }
        s.push_back(t);
    }
    Quote Originally Posted by manasij7479
    btw_ this is for parsing the input for a calculator program...
    Any idea what is going wrong...or a better way to put the different parts of the input line to be analysed separately later?
    Well, it might be better to read into a vector of strings first since your tokens are separated by whitespace. Then, you iterate over this vector and attempt each conversion to double.

    Quote Originally Posted by Sipher
    No copy constructor or assignment operator... how do you expect push_back to work properly?
    The compiler generated versions will suffice. That said, two constructors for the sake of convenience would have been nice.
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  4. #4
    Programming Wraith GReaper's Avatar
    Join Date
    Apr 2009
    Location
    Greece
    Posts
    2,738
    Quote Originally Posted by laserlight View Post
    The compiler generated versions will suffice.
    Sorry, but i have to second this statement. If you haven't noticed, he included a "string" inside his class.
    Devoted my life to programming...

  5. #5
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    Quote Originally Posted by Sipher
    Sorry, but i have to second this statement. If you haven't noticed, he included a "string" inside his class.
    Yeah, but I'm assuming that it refers to std::string, especially given that using namespace std and a stringstream is used.
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  6. #6
    Programming Wraith GReaper's Avatar
    Join Date
    Apr 2009
    Location
    Greece
    Posts
    2,738
    Quote Originally Posted by laserlight View Post
    Yeah, but I'm assuming that it refers to std::string, especially given that using namespace std and a stringstream is used.
    But, string's constructor won't be called as all the compiler does is binary copy!
    Devoted my life to programming...

  7. #7
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    Quote Originally Posted by Sipher
    But, string's constructor won't be called as all the compiler does is binary copy!
    No, that is a misconception.
    Quote Originally Posted by C++03 Clause 12.8 Paragraph 4 (part)
    If the class definition does not explicitly declare a copy constructor, one is declared implicitly. Thus, for the class definition
    Code:
    struct X {
        X(const X&, int);
    };
    a copy constructor is implicitly-declared.
    Quote Originally Posted by C++03 Clause 12.8 Paragraph 8
    The implicitly-defined copy constructor for class X performs a memberwise copy of its subobjects. The order of copying is the same as the order of initialization of bases and members in a user-defined constructor (see 12.6.2). Each subobject is copied in the manner appropriate to its type:
    — if the subobject is of class type, the copy constructor for the class is used;
    — if the subobject is an array, each element is copied, in the manner appropriate to the element type;
    — if the subobject is of scalar type, the built-in assignment operator is used.
    Virtual base class subobjects shall be copied only once by the implicitly-defined copy constructor (see 12.6.2).
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  8. #8
    Programming Wraith GReaper's Avatar
    Join Date
    Apr 2009
    Location
    Greece
    Posts
    2,738
    Well, how about that? Thanks laserlight! I guess i messed C++ with C .

    EDIT: Was that feature included after C++03? Maybe i haven't heard of it because few people know it... I know it now!
    Last edited by GReaper; 02-02-2011 at 07:57 AM.
    Devoted my life to programming...

  9. #9
    [](){}(); manasij7479's Avatar
    Join Date
    Feb 2011
    Location
    *nullptr
    Posts
    2,657
    for( ; ; )
    Would it know when the input ends?

    st.clear();
    Won't the stream start from the beginning if this is used ?

    might be better to read into a vector of strings
    How do I do it? ... it was apparently the aim of this little code snippet ultimately(with something indicating whether the tokens are operators or operands)!! .... It would be much better if it is done in one step.

  10. #10
    Programming Wraith GReaper's Avatar
    Join Date
    Apr 2009
    Location
    Greece
    Posts
    2,738
    Quote Originally Posted by manasij7479 View Post
    Would it know when the input ends?
    The "break" jumps off the loop when needed.
    Devoted my life to programming...

  11. #11
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    Quote Originally Posted by manasij7479
    Would it know when the input ends?
    That is what the break is for.

    Quote Originally Posted by manasij7479
    Won't the stream start from the beginning if this is used ?
    No, this clears the error state. Warning: I have not tested the code, and it might be more complex than necessary.

    Quote Originally Posted by manasij7479
    How do I do it? ... it was apparently the aim of this little code snippet ultimately(with something indicating whether the tokens are operators or operands)!! .... It would be much better if it is done in one step.
    It is your choice. My suggestion could make it easier.
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  12. #12
    [](){}(); manasij7479's Avatar
    Join Date
    Feb 2011
    Location
    *nullptr
    Posts
    2,657
    Quote Originally Posted by Sipher View Post
    The "break" jumps off the loop when needed.
    oh..overlooked it...btw Can the else-break block be executed in any other case ?

  13. #13
    [](){}(); manasij7479's Avatar
    Join Date
    Feb 2011
    Location
    *nullptr
    Posts
    2,657
    Quote Originally Posted by laserlight View Post
    It is your choice. My suggestion could make it easier.
    That would be my choice if you tell me how to do it...give some suggestions...please..

  14. #14
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    Well, you don't have to read the line into a vector of strings, but you could read each lexeme into a string, and then determine the token type from the string, e.g.,
    Code:
    string line;
    getline(cin, line);
    
    stringstream ss(line);
    vector<token> token_list;
    string lexeme;
    while (ss >> lexeme)
    {
        token_list.push_back(token(lexeme));
    }
    In the above example, I am using a yet-to-be-defined constructor for token that takes a string argument and determines the token type from there. If the token is actually of double type, it would store the converted double value, otherwise it would just store the string. (In fact, instead of the status member variable, use a member variable of say, enum type to store the token type.)
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  15. #15
    [](){}(); manasij7479's Avatar
    Join Date
    Feb 2011
    Location
    *nullptr
    Posts
    2,657
    Got the rest of it.....would reduce the complexity to a great extent....but what do you mean about the enum?....would it be of any advantage over the bool?

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Why does this code produce infinite loop?
    By matchkop in forum C Programming
    Replies: 15
    Last Post: 05-25-2010, 09:52 AM
  2. Using while produces an infinite loop...
    By UCF43 in forum C Programming
    Replies: 4
    Last Post: 04-01-2010, 04:47 PM
  3. Replies: 2
    Last Post: 06-14-2009, 11:24 PM
  4. Cosine fucntion and infinite loop.
    By youareafever in forum C Programming
    Replies: 2
    Last Post: 11-07-2008, 04:45 AM
  5. Switch statement = infinite loop
    By Lucid003 in forum C++ Programming
    Replies: 10
    Last Post: 10-10-2005, 12:46 AM

Tags for this Thread