By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
446,167 Members | 1,029 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 446,167 IT Pros & Developers. It's quick & easy.

g++ question, bug?

P: n/a
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?
Jul 19 '05 #1
Share this Question
Share on Google+
7 Replies


P: n/a

"Kevin Stern" <K-*****@neiu.edu> wrote in message news:ca**************************@posting.google.c om...
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?


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).

Jul 19 '05 #2

P: n/a
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" <ro*@sensor.com> wrote in message news:<3f***********************@news.newshosting.c om>...
"Kevin Stern" <K-*****@neiu.edu> wrote in message news:ca**************************@posting.google.c om...
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?


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).

Jul 19 '05 #3

P: n/a
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" <ro*@sensor.com> wrote in message news:<3f***********************@news.newshosting.c om>...
"Kevin Stern" <K-*****@neiu.edu> wrote in message news:ca**************************@posting.google.c om...
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?


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).

Jul 19 '05 #4

P: n/a
Kevin Stern wrote:
Ok, tell me THIS makes any sense!

It does seem to work oddly in -icanon mode.
Jul 19 '05 #5

P: n/a
Kevin Stern wrote:

(Please don't top-post. Read section 5 of the FAQ for posting
guidelines: http://www.parashift.com/c++-faq-lite/)
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;
'a' is not initialized
char nl = (char) 10;
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_cast) 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'.
std::cout << "Enter: ";
while (a != 'g') {


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.

Jul 19 '05 #6

P: n/a
> (Please don't top-post. Read section 5 of the FAQ for posting
guidelines: http://www.parashift.com/c++-faq-lite/)
Will do.
I have created the following program:

#include <iostream>

int main() {
char a;


'a' is not initialized


True.
char nl = (char) 10;
Very bad idea.


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.
2) Don't use C-style casts. Use C++ cast operators (static_cast,
dynamic_cast, const_cast, reinterpret_cast) instead. C-style casts are
far too dangerous.
I think we're off topic here :)
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'.
Still a bit off topic.
std::cout << "Enter: ";
while (a != 'g') {


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


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.
Sorry, I'm not addressing your actual question, it looks like that's
been handled. I just wanted to point out these problems.


Yep. Nope. Thanks.
Jul 19 '05 #7

P: n/a
Kevin Stern wrote:

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.
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.

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

I think we're off topic here :)


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.

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'.

Still a bit off topic.


Nope, perfectly on-topic.

std::cout << "Enter: ";
while (a != 'g') {
Attempting to use the uninitialized variable 'a' invokes undefined behavior.

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.


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.

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

Yep. Nope. Thanks.


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><enter>. 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.

Jul 19 '05 #8

This discussion thread is closed

Replies have been disabled for this discussion.