You are not logged in.

#1 2009-11-27 22:01:22

bfo
Member
Registered: 2009-11-27
Posts: 44

[SOLVED][g++] Strange behaviour within loops

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

#2 2009-11-27 22:09:25

Cerebral
Forum Fellow
From: Waterloo, ON, CA
Registered: 2005-04-08
Posts: 3,108
Website

Re: [SOLVED][g++] Strange behaviour within loops

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

#3 2009-11-27 22:11:54

mikesd
Member
From: Australia
Registered: 2008-02-01
Posts: 788
Website

Re: [SOLVED][g++] Strange behaviour within loops

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

#4 2009-11-28 01:27:13

llcawthorne
Member
From: Columbia, SC
Registered: 2009-10-16
Posts: 142

Re: [SOLVED][g++] Strange behaviour within loops

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

#5 2009-11-28 01:51:19

djgera
Developer
From: Buenos Aires - Argentina
Registered: 2008-12-24
Posts: 723
Website

Re: [SOLVED][g++] Strange behaviour within loops

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

#6 2009-11-28 05:59:38

Trent
Member
From: Baltimore, MD (US)
Registered: 2009-04-16
Posts: 990

Re: [SOLVED][g++] Strange behaviour within loops

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

#7 2009-11-28 07:47:13

llcawthorne
Member
From: Columbia, SC
Registered: 2009-10-16
Posts: 142

Re: [SOLVED][g++] Strange behaviour within loops

Trent wrote:

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.

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

#8 2009-11-28 15:02:53

bfo
Member
Registered: 2009-11-27
Posts: 44

Re: [SOLVED][g++] Strange behaviour within loops

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

#9 2009-11-28 15:13:02

sr
Member
Registered: 2009-10-12
Posts: 51

Re: [SOLVED][g++] Strange behaviour within loops

Just for fun big_smile 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

#10 2009-11-28 16:24:05

Trent
Member
From: Baltimore, MD (US)
Registered: 2009-04-16
Posts: 990

Re: [SOLVED][g++] Strange behaviour within loops

bfo wrote:

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! smile)

Incidentally, you might want to look at getchar/putchar/puts (fgetc/fputc/fputs) if speed is your main concern.

Offline

Board footer

Powered by FluxBB