g++ question, bug?

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • Kevin Stern

    g++ question, bug?

    Hi All,

    Here is a program I wrote and compiled using g++

    #include <iostream>
    int main() {
    char a;
    std::cin.get(a) ;
    std::cout << a;
    std::cin.ignore (100, '\n');
    }

    The problem is ... I expect that if I type one or more characters when
    the program pauses for input on the cin.get, the cin.ignore will find
    a '\n' on the input stream and not pause. Unfortunately, it pauses!
    Any ideas?
  • Ron Natalie

    #2
    Re: g++ question, bug?


    "Kevin Stern" <K-Stern@neiu.edu> wrote in message news:ca77e32d.0 308200721.64e8d acf@posting.goo gle.com...
    [color=blue]
    > The problem is ... I expect that if I type one or more characters when
    > the program pauses for input on the cin.get, the cin.ignore will find
    > a '\n' on the input stream and not pause. Unfortunately, it pauses!
    > Any ideas?[/color]

    THis has nothing to do with either C++ or your particular implementation.
    It has to do with the way the terminal interface works on your system
    (presumably UNIX). The default mode on UNIX buffers up your typing
    until you press enter (or newline or return depending on the configuration).
    This allows you to use things like the backspace and line kill keys without
    having to bulid that behavior into every program.

    Look up "RAW" or "CBREAK" modes in the manual (may be under stty or ioctl).



    Comment

    • Kevin Stern

      #3
      Re: g++ question, bug?

      Thanks for the info ... I am left with a couple of questions, though.

      I have created the following program:

      #include <iostream>

      int main() {
      char a;
      char nl = (char) 10;
      std::cout << "Enter: ";
      while (a != 'g') {
      std::cin.get(a) ;
      std::cout << "a=" << (int)a;
      //std::cin.ignore (500, nl);
      }
      std::cout << "Gimme Input: ";
      std::cin >> a;
      }

      If I hit a key, say j, and then [enter] it outputs:

      a=106a=10

      If I uncomment the cin.ignore ... the ignore statement waits for me to
      hit enter!

      The reason this looks like a bug is that if my cin.get can find a
      character on the input stream with ascii code 10 (i.e. the enter key),
      then how can it be explained that the cin.ignore cannot find one and
      waits for the enter key to be hit?

      I don't see what this has to do with buffering input, if someone could
      explain a bit more about this buffer ... I assume it buffers the input
      until the enter key is hit and then dumps the buffer to the input
      stream ... this should not screw up my program.

      Thanks.

      "Ron Natalie" <ron@sensor.com > wrote in message news:<3f4392ab$ 0$13204$9a6e19e a@news.newshost ing.com>...[color=blue]
      > "Kevin Stern" <K-Stern@neiu.edu> wrote in message news:ca77e32d.0 308200721.64e8d acf@posting.goo gle.com...
      >[color=green]
      > > The problem is ... I expect that if I type one or more characters when
      > > the program pauses for input on the cin.get, the cin.ignore will find
      > > a '\n' on the input stream and not pause. Unfortunately, it pauses!
      > > Any ideas?[/color]
      >
      > THis has nothing to do with either C++ or your particular implementation.
      > It has to do with the way the terminal interface works on your system
      > (presumably UNIX). The default mode on UNIX buffers up your typing
      > until you press enter (or newline or return depending on the configuration).
      > This allows you to use things like the backspace and line kill keys without
      > having to bulid that behavior into every program.
      >
      > Look up "RAW" or "CBREAK" modes in the manual (may be under stty or ioctl).[/color]

      Comment

      • Kevin Stern

        #4
        Re: g++ question, bug?

        Ok, tell me THIS makes any sense!


        Program:

        #include <iostream>

        int main() {
        char a;
        char nl = (char) 10;
        while (a != 'g') {
        std::cout << "Enter: ";
        std::cin.get(a) ;
        std::cout << "a=" << (int)a << std::endl;
        std::cin.ignore ();
        std::cout << "end ignore" << std::endl;
        }
        std::cout << "Gimme Input: ";
        std::cin >> a;
        }

        Output:
        _______________ _______________ _______________ _______
        Enter: a[Enter Key]
        a=97
        b[Enter Key]
        end ignore
        Enter: a=98
        c[Enter Key]
        end ignore
        Enter: a=99
        [Enter Key]
        end ignore
        Enter: a=10
        [Enter Key]
        [Enter Key]
        end ignore
        Enter: a=10
        f[Enter Key]
        end ignore
        Enter: a=10
        _______________ _______________ _______________ ____

        "Ron Natalie" <ron@sensor.com > wrote in message news:<3f4392ab$ 0$13204$9a6e19e a@news.newshost ing.com>...[color=blue]
        > "Kevin Stern" <K-Stern@neiu.edu> wrote in message news:ca77e32d.0 308200721.64e8d acf@posting.goo gle.com...
        >[color=green]
        > > The problem is ... I expect that if I type one or more characters when
        > > the program pauses for input on the cin.get, the cin.ignore will find
        > > a '\n' on the input stream and not pause. Unfortunately, it pauses!
        > > Any ideas?[/color]
        >
        > THis has nothing to do with either C++ or your particular implementation.
        > It has to do with the way the terminal interface works on your system
        > (presumably UNIX). The default mode on UNIX buffers up your typing
        > until you press enter (or newline or return depending on the configuration).
        > This allows you to use things like the backspace and line kill keys without
        > having to bulid that behavior into every program.
        >
        > Look up "RAW" or "CBREAK" modes in the manual (may be under stty or ioctl).[/color]

        Comment

        • Ron Natalie

          #5
          Re: g++ question, bug?

          Kevin Stern wrote:[color=blue]
          > Ok, tell me THIS makes any sense!
          >[/color]
          It does seem to work oddly in -icanon mode.


          Comment

          • Kevin Goodsell

            #6
            Re: g++ question, bug?

            Kevin Stern wrote:

            (Please don't top-post. Read section 5 of the FAQ for posting
            guidelines: http://www.parashift.com/c++-faq-lite/)
            [color=blue]
            > Thanks for the info ... I am left with a couple of questions, though.
            >
            > I have created the following program:
            >
            > #include <iostream>
            >
            > int main() {
            > char a;[/color]

            'a' is not initialized
            [color=blue]
            > char nl = (char) 10;[/color]

            Very bad idea.

            1) Don't assume a particular value for any given character. A newline is
            '\n'. The value representing it could be just about anything.

            2) Don't use C-style casts. Use C++ cast operators (static_cast,
            dynamic_cast, const_cast, reinterpret_cas t) instead. C-style casts are
            far too dangerous.

            3) Don't cast at all unless you absolutely have to. There's no reason
            for this cast, especially if you replace the 10 with '\n'.
            [color=blue]
            > std::cout << "Enter: ";
            > while (a != 'g') {[/color]

            Attempting to use the uninitialized variable 'a' invokes undefined behavior.

            Sorry, I'm not addressing your actual question, it looks like that's
            been handled. I just wanted to point out these problems.

            -Kevin
            --
            My email address is valid, but changes periodically.
            To contact me please use the address from a recent posting.

            Comment

            • Kevin Stern

              #7
              Re: g++ question, bug?

              > (Please don't top-post. Read section 5 of the FAQ for posting[color=blue]
              > guidelines: http://www.parashift.com/c++-faq-lite/)[/color]

              Will do.
              [color=blue][color=green]
              > > I have created the following program:
              > >
              > > #include <iostream>
              > >
              > > int main() {
              > > char a;[/color]
              >
              > 'a' is not initialized[/color]

              True.
              [color=blue]
              >[color=green]
              > > char nl = (char) 10;[/color]
              >
              > Very bad idea.[/color]

              Let me clarify. I used \n ... ignore did not work, I read the std.
              input and I kept getting the character that I pressed plus a character
              with ascii value 10 (the enter key). Just in case the \n was giving
              problems I figured I'd use the actual ascii value that I wanted to
              ignore.
              [color=blue]
              > 2) Don't use C-style casts. Use C++ cast operators (static_cast,
              > dynamic_cast, const_cast, reinterpret_cas t) instead. C-style casts are
              > far too dangerous.[/color]

              I think we're off topic here :)
              [color=blue]
              > 3) Don't cast at all unless you absolutely have to. There's no reason
              > for this cast, especially if you replace the 10 with '\n'.[/color]

              Still a bit off topic.
              [color=blue][color=green]
              > > std::cout << "Enter: ";
              > > while (a != 'g') {[/color]
              >
              > Attempting to use the uninitialized variable 'a' invokes undefined behavior.[/color]

              a is initialized with the std::cin.get so it's something from the
              input stream ... you seem to be missing the point ... this is a test
              program not something I'm selling.
              [color=blue]
              > Sorry, I'm not addressing your actual question, it looks like that's
              > been handled. I just wanted to point out these problems.[/color]

              Yep. Nope. Thanks.

              Comment

              • Kevin Goodsell

                #8
                Re: g++ question, bug?

                Kevin Stern wrote:[color=blue]
                >
                > Let me clarify. I used \n ... ignore did not work, I read the std.
                > input and I kept getting the character that I pressed plus a character
                > with ascii value 10 (the enter key). Just in case the \n was giving
                > problems I figured I'd use the actual ascii value that I wanted to
                > ignore.[/color]

                I'm not sure I understand, but it sounds like you ran into a problem
                using your input stream. ignore() with a sufficiently large 1st argument
                should remove whatever's left of the line, including the '\n' (assuming
                that's what you use for the terminator). If that isn't the behavior you
                observed then there's a problem with the code or the library. The code
                you posted had the ignore() call commented out. It looks like it would
                have worked (well, sort of) with that call in place.
                [color=blue]
                >
                >[color=green]
                >>2) Don't use C-style casts. Use C++ cast operators (static_cast,
                >>dynamic_cas t, const_cast, reinterpret_cas t) instead. C-style casts are
                >>far too dangerous.[/color]
                >
                >
                > I think we're off topic here :)[/color]

                Not at all. We're talking about C++, which is the topic of this group.
                If you meant that we are straying from your question, well, I never saw
                the original post, and it appears from the replies that it was a
                platform-specific problem, so technically that's the discussion that
                would be off-topic.
                [color=blue]
                >
                >[color=green]
                >>3) Don't cast at all unless you absolutely have to. There's no reason
                >>for this cast, especially if you replace the 10 with '\n'.[/color]
                >
                >
                > Still a bit off topic.[/color]

                Nope, perfectly on-topic.
                [color=blue]
                >
                >[color=green][color=darkred]
                >>> std::cout << "Enter: ";
                >>> while (a != 'g') {[/color]
                >>
                >>Attempting to use the uninitialized variable 'a' invokes undefined behavior.[/color]
                >
                >
                > a is initialized with the std::cin.get so it's something from the
                > input stream ... you seem to be missing the point ... this is a test
                > program not something I'm selling.[/color]

                I'm not missing any point, because I was not addressing any particular
                point. I was talking about the code itself, which does, in fact, invoke
                undefined behavior due to the error I pointed out. 'a' is obviously NOT
                initialized by the std::cin.get, since you are quite clearly testing 'a'
                *before* that call occurs. Hence, you are examining the value of a
                variable that is indeterminate, and the behavior is undefined.
                [color=blue]
                >
                >[color=green]
                >>Sorry, I'm not addressing your actual question, it looks like that's
                >>been handled. I just wanted to point out these problems.[/color]
                >
                >
                > Yep. Nope. Thanks.[/color]

                Your problem has not been handled?

                ....

                OK, fair enough. Let me take another look. Here's the code (with changes
                to make it well-defined):

                #include <iostream>

                int main() {
                char a = 0; // initialized
                // char nl = (char) 10; // no need for this
                std::cout << "Enter: ";
                while (a != 'g') {
                std::cin.get(a) ;
                std::cout << "a=" << (int)a;
                //std::cin.ignore (500, '\n');
                }
                std::cout << "Gimme Input: ";
                std::cin >> a;

                return 0; // added (not strictly required)
                }

                With this, I see output similar to what you reported, and I'm not
                surprised. Now, if I uncomment the ignore() call it waits for a line of
                input, then gives the character value of the first character in that
                line, and waits for another line of input (until the first character is
                'g'). This is the expected behavior. You said:

                If I uncomment the cin.ignore ... the ignore statement waits for me to
                hit enter!

                The reason this looks like a bug is that if my cin.get can find a
                character on the input stream with ascii code 10 (i.e. the enter key),
                then how can it be explained that the cin.ignore cannot find one and
                waits for the enter key to be hit?
                I don't quite understand this. Neither get() nor ignore() can find the
                'enter' value unless you press 'enter'. Presumably, your keyboard input
                is something like this: <a><enter><p><e nter>. Now, if the ignore() call
                is not present, get() finds 'a', 'enter', 'p', 'enter' in that order,
                and the program outputs the value for each (four total). With the ignore
                call, get() finds 'a', then ignore() removes the 'enter', then get()
                finds 'p', then ignore() removes the second 'enter'.

                If this doesn't help you understand what is happening, or if you believe
                what I'm describing is not what you are observing, then please clarify
                what you expected and what you actually observed.

                -Kevin
                --
                My email address is valid, but changes periodically.
                To contact me please use the address from a recent posting.

                Comment

                Working...