You are not logged in.
Hello
I've recently installed Arch64 on lappy. It will be used mostly for programming, therefore that's the thing which really makes me anxious: namely, loops doesn't work as they should. They seem to be skipping one iteration. As far as I have investigated, it happens when i use scanf.
Here's the code that doesn't work for me:
#include <cstdio>
using namespace std;
int main(int argc, char ** argv)
{
char tmp;
int index = 0;
do
{
printf("%d\n", index++);
printf("Enter char: ");
scanf("%c", &tmp);
printf("ASCII: %d\n", tmp);
}
while(tmp != '~');
return 0;
}
Here's what I get in terminal:
0
Enter char: l
ASCII: 108
1
Enter char: ASCII: 10
2
Enter char:
Step with number 1 is definitely not ok.
Some useful info:
glibc 2.11-1
gcc 4.4.2-3
Linux asus 2.6.31-ARCH #1 SMP PREEMPT Tue Nov 10 19:01:40 CET 2009 x86_64 Intel(R) Core(TM)2 Duo CPU T6600 @ 2.20GHz GenuineIntel GNU/Linux
Thanks in advance for telling me what I miss here.
Last edited by bfo (2009-11-28 15:03:33)
Offline
ASCII 10 is your enter key.
0
Enter char: Cerebral
ASCII: 67
1
Enter char: ASCII: 101
2
Enter char: ASCII: 114
3
Enter char: ASCII: 101
4
Enter char: ASCII: 98
5
Enter char: ASCII: 114
6
Enter char: ASCII: 97
7
Enter char: ASCII: 108
8
Enter char: ASCII: 10
9
Enter char:
Offline
I'm a bit rusty on C but this is correct behaviour. The second iteration through the loop reads the left over line feed in the scan buffer. Solutions to fix this woud be to flush the buffer or maybe read a string instead of the character.
Offline
Other people already explained the problem, but here's a simple code example for if you just want to clear the '\n' from the buffer and aren't expecting to use advanced error checking, this works (on my box):
#include <cstdio>
using namespace std;
int main(int argc, char ** argv)
{
char tmp;
int index = 0;
do
{
printf("%d\n", index++);
printf("Enter char: ");
scanf("%c", &tmp);
getchar(); //clear the left over '\n'
printf("ASCII: %d\n", tmp);
}
while(tmp != '~');
return 0;
}
To understand recursion, you must understand recursion.
Offline
use the pair fgets/sscanf
char x;
char buf[3];
fgets(buf, sizeof(buf), stdin);
sscanf(buf, "%c", &x);
EDIT: but this is more C than C++
Last edited by djgera (2009-11-28 01:52:50)
Offline
May I suggest that scanf is not what you want. In fact, scanf is almost never what you want, as described here:
http://c-faq.com/stdio/scanfprobs.html
But your code is more C-like than C++-like (from what I understand; I know very little C++). Surely there is a more idiomatic way to read characters from stdin in C++? Perhaps someone can educate me.
Offline
May I suggest that scanf is not what you want. In fact, scanf is almost never what you want, as described here:
http://c-faq.com/stdio/scanfprobs.htmlBut your code is more C-like than C++-like (from what I understand; I know very little C++). Surely there is a more idiomatic way to read characters from stdin in C++? Perhaps someone can educate me.
This would work in C++ (not sure it is the easiest way though, but it's easy to read):
#include <iostream>
using namespace std;
int main(int argc, char* argv[]) {
char tmp;
int index = 0;
do {
cout << index++ << endl;
cout << "Enter char: ";
cin >> tmp;
cout << "ASCII: " << static_cast<int>(tmp) << endl;
} while (tmp != '~');
return 0;
}
cin ignores white space too, so you don't have to worry about things like '\n'.
To understand recursion, you must understand recursion.
Offline
Thank you for all the answers. Unfotunately, I don't want to use cin/cout even with sync_with_stdio(0), because it's still slower than traditional scanf/printf pair, which in turn is much useful in programming contests of all kind. Solved then :-)
Offline
Just for fun and perhaps completeness, "idiomatic" C++ that cheats a bit:
#include <iostream>
#include <iterator>
using namespace std;
int main(int, char*[])
{
copy(istream_iterator<char>(cin),
istream_iterator<char>(),
ostream_iterator<int>(cout, " in ASCII\n"));
return 0;
}
Offline
Thank you for all the answers. Unfotunately, I don't want to use cin/cout even with sync_with_stdio(0), because it's still slower than traditional scanf/printf pair, which in turn is much useful in programming contests of all kind. Solved then :-)
When you're working interactively, speed of I/O methods is not an issue. Any contest that deducts points for using a "slow" method of I/O when waiting for user input, which is slow by nature, is not a contest I would bother to try to win. (Who cares if I took last place? I'm right! )
Incidentally, you might want to look at getchar/putchar/puts (fgetc/fputc/fputs) if speed is your main concern.
Offline