getline not working properly

So, I'm trying to do something simple: get a line into a string, and I have this:
getline (ins, temp);
But, it never seems to stop, in that I hit enter as many times as I want and get nothing. Why? Thanks in advance!
Try substituting cin for ins
ins is an input stream, so that wouldn't really be helpful. I did try that though, and it did the same thing as before. This is embedded in a function inside of a class, I can post the entire function if it would be helpful, not that it gets to the rest of the function.
Did you actually enter a character? IIRC getline will ignore newlines that come before any other characters were read.
Yes, I enter three letters, each followed by a space. This is part of the extraction operator (>>) for a class that describes a resistor. The idea is to read in the line, determine how many spaces are present, if none, then the user entered just the numeric value, so I would then convert it to an integer, if two then I use a switch statement to assign the colors of the resistor. Here is the code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
istream & operator >> (istream & ins, const Resistor & resi)
{
    string temp;
    int numspaces(0), pos(0);

    getline (ins, temp);

    cout << "here";

    while (pos < temp.length())
    {
        if (temp.find(' ') >= 0)
        {
            numspaces++;
            pos = temp.find(' ') + 1;
        }
        else
        {
            pos = temp.length();
        }
    }

    cout << numspaces;
    return ins;
}

I stopped at this point to see if my logic for determining number of spaces was correct, but I'm never seeing here printed to the screen. I'm sure its something simple.
Just to make sure... you are calling it like this:
cin>>resi;
and enter something like
a b c ENTER
? In that case, I have really no idea what could be causing this. What compiler are you using, and what command line client? May be a bug.

PS: Shouldn't the Resistor argument be nonconst when you're writing an extraction operator?
Last edited on
Yes to the first two. I'm using an IDE called Code::Blocks, which using GCC. I have considered it, but I have a hard time believing in anything being noticeably wrong with GCC, though I'll look into it. Ahhh, yes, you are right, not that I think that is affecting it...I probably would have run into that later lol. Thanks for pointing it out, probably would have been a headache later!
Do you use the GCC version that's being shipped with Code::Blocks? I am not sure, but it might be an outdated one. Oh, and what OS are you using? Windows? Then are you using MinGW or Cygwin GCC?
Code::Blocks says GCC 4.3.2 32-bit, and I'm using Code::Blocks 10.05. I'm running an Ubuntu based Linux distro called UberStudent. I can post the entire class if it would be helpful.
Oh, I just discovered that if I type only one letter followed by a space and then hit enter, it works. It must be one letter only, followed by a space.
When outputting debugging and errors messages use cerr instead of cout. (the output is flushed)

1
2
3
4
5
6
7
    while (pos < temp.length())
    {
        if (temp.find(' ') >= 0) //you always start looking from the beginning 
        {
            numspaces++;
            pos = temp.find(' ') + 1;
        }
I'll keep that in mind. Thanks for the loop, though that is not the problem seeing as it never gets there. Fixed code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
istream & operator >> (istream & ins, Resistor & resi)
{
    string temp;
    int numspaces(0), pos(0);

    getline(ins, temp);

    cout << "here";

    while (pos < temp.length())
    {
        if (temp.find(' ', pos) >= 0)
        {
            numspaces++;
            pos = temp.find(' ', pos) + 1;
        }
        else
        {
            pos = temp.length();
        }
    }

    cout << numspaces;
    return ins;
}
Last edited on
I wanted to clarify, by fixed I was only referring to the pointed out issues, it still doesn't work lol
Well, that's interesting. I was just adding comments, so I recompiled, and what do you know it works...sort of. If you type "a b c" it doesn't work, but if you type "a b c " it does, it relies on that last space.. Strange that I tried that before and it didn't work!
You didn't fixed the cout. Check out your processor usage, it enter in an infinite loop.

http://www.cplusplus.com/reference/string/string/find/
If the content is not found, the member value npos is returned.
1
2
//if (temp.find(' ', pos) >= 0)
if( temp.find(' ', pos) != std::string::npos )
I'll go ahead and change it since I think that is the more accepted way, but it doesn't infinite loop, and it did return the right value. I'll leave this open for a day to see if anybody can figure out why the space is necessary for it to work and then I'll mark as solved.
getline is again giving me trouble, this time it throw a segmentation fault. Here is the new code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
istream & operator >> (istream & ins, Resistor & resi)
{
    string temp;    //For the line
    int numspaces(0), pos(0);

    getline(ins, temp); //Get the line
    cout << temp;

    while (pos < temp.length()) //While we still have a string to search
    {
        if (temp.find(' ', pos) != std::string::npos)   //Find a space starting at pos
        {
            cout << "here";
            numspaces++;    //Increase number of spaces
            pos = temp.find(' ', pos) + 1;  //Update position
        }
        else    //No space was found
        {
            pos = temp.length();    //End the loop
        }
    }

    cout << numspaces;

    switch (numspaces)
    {
        case 0:
            resi.set_resistance(atoi(temp.c_str()));
            break;
        case 2:
            pos = 0;
            string temp2;

            for (int count = 0;count < 3;count++)
            {
                temp2 = temp.substr(pos, temp.find(' ', pos) - pos - 1);

                pos = temp.find(' ', pos);

                resi.colors[count] = static_cast<ColorCode>(resi.int_equ(temp2));
            }

            resi.convert_to_int();
            break;
    }

    return ins;
}

If I type "47000", it works. If I type "yellow violet orange" is says segmentation fault. It worked once too...so strange.
Assuming that the colours array has the right dimension
1
2
3
  //if you already passed by an space
temp2 = temp.substr(pos, temp.find(' ', pos) - pos - 1); //second argument is -1 (subtract all you can)
  pos = temp.find(' ', pos); //pos is not changing 
So temp2 = " violet orange", maybe that is causing issues in Resistor::int_equ or later on Resistor::convert_to_int
Good point, but the problem is that it never gets there, I put a cout right after the getline, and the line entered is never outputted, it just returns Segmentation Fault.
*sigh*
That's because cout is buffered. Flush the output with cout << flush; or cout << endl; or change cout to cerr (that is not buffered)
Topic archived. No new replies allowed.