3
votes

Sorry for the probably dumb question, but i wanted to practice loops a bit and came out with this idea.Basically it ask you to enter or not in a loop and when you're in, it ask you for something to do.The problem is that just after i enter the loop it prints two times the printf string before passing to the scanf one and waiting for an input. I can't figure it out. All help is welcome! Here's the code:

#include <stdio.h>

int main() 
{
    char check = 'a';
    char int_check = 'a';
    int b = 0;
    printf("want to go in? [y or n]\n");
    scanf("%c",&check);
    if ( check == 'y') {
        while (1){
            printf("Waiting: \n");
            scanf("%c",&int_check);
            if ( int_check == 'q'){
                printf("You're out, bye!\n");
                break;
            };
        };
    } else if ( check == 'n'){
        printf("You're not in, see ya!\n");
    }else {
        printf("Please, type 'y' or 'n'\n");
    };
    return 0;
}
2
I'm not sure if it's an error-error, but you shouldn't have all those semicolons after your curly braces. - Dan Fego
@DanFego It's silly (or at least I find it so), but it doesn't matter. It's treated as a NOP statement IIRC. - user166390
You press "y" and then hit return. That's two characters, "y" & "\n". "y" is read in by the pre-loop scanf, and the first scanf in the loop finds the newline character still in the buffer. - maligree
@pst: Look in the scanf line in the while loop. The destination has a space in it. This is a good solid case for teaching good style when someone is learning a language (e.g., having a space after commas in an argument list, etc.). - Platinum Azure
yeah that space is an edit error, it isn't int the original programm, sorry :( EDIT: fixed now - WhiteEyeTree

2 Answers

4
votes

If you input onto a terminal the following:

x

The first loop will see an x

The second loop will see a newline character.

The easiest way to work around this is to use sscanf and getline.

2
votes

You can change the program to respond to keyboard immediately, i.e. without waiting for the user to press enter. It requires changing the properties of the input terminal, and is generally messier and less portable-seeming than line-oriented input. This page describes how to do it, and here is the code modified to work that way:

#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <termios.h>

struct termios saved_settings;

void
reset_term_mode(void)
{
  tcsetattr (STDIN_FILENO, TCSANOW, &saved_settings);
}

int main() 
{
    tcgetattr(STDIN_FILENO, &saved_settings);
    atexit(reset_term_mode);

    struct termios term_settings;

    tcgetattr(STDIN_FILENO, &term_settings);
    term_settings.c_lflag &= ~(ICANON|ECHO);
    term_settings.c_cc[VMIN] = 1;
    term_settings.c_cc[VTIME] = 0;
    tcsetattr(STDIN_FILENO, TCSAFLUSH, &term_settings);

    char check = 'a';
    char int_check = 'a';
    int b = 0;
    printf("want to go in? [y or n]\n");
    scanf("%c",&check);
    if ( check == 'y') {
        while (1){
            printf("Waiting: \n");
            scanf("%c", &int_check);
            if ( int_check == 'q'){
                printf("You're out, bye!\n");
                break;
            };
        };
    } else if ( check == 'n'){
        printf("You're not in, see ya!\n");
    }else {
        printf("Please, type 'y' or 'n'\n");
    };
    return 0;
}