LinuxQuestions.org

LinuxQuestions.org (/questions/)
-   Programming (https://www.linuxquestions.org/questions/programming-9/)
-   -   Howto use getchar() multiple times? (https://www.linuxquestions.org/questions/programming-9/howto-use-getchar-multiple-times-571937/)

daYz 07-24-2007 12:47 PM

Howto use getchar() multiple times?
 
Hi,

Can someone tell me why the second getchar(); in the following code is skipped, and can you show me what would be the correct way of doing this?

Code:

#include <stdio.h>

main()



getchar();

getchar();

return 0;

}

Thanks.

Regards,

Ben

jlliagre 07-24-2007 01:44 PM

Not that there are no issues with your program, but what makes you feel the second getchar() is skipped given the fact you do not get its return value.

95se 07-24-2007 02:16 PM

Given your rather short post, I can only guess that you don't realize that the new line entered when you press return is a character as well and that it is what the second getchar is returning. If this is not what your talking about, we're going to need a short example (ie. input, expected output, actual output) or something, because it should work otherwise.

daYz 07-24-2007 02:38 PM

Quote:

Originally Posted by 95se
Given your rather short post, I can only guess that you don't realize that the new line entered when you press return is a character as well and that it is what the second getchar is returning. If this is not what your talking about, we're going to need a short example (ie. input, expected output, actual output) or something, because it should work otherwise.

That is exactly what I mean. I was not aware of that.

Thanks for your help guys.

Regards,

Ben

jlliagre 07-24-2007 03:02 PM

Beware that your program is using the default cooked (buffered) tty mode, which is inconvenient with getchar. You may want to have a look at this thread about the issue and some solutions to fix it: http://www.linuxquestions.org/questi...d.php?t=122663

daYz 07-24-2007 04:08 PM

Thanks jlliagre :). I am going to look at this tommorow.

Ben

ta0kira 07-24-2007 05:49 PM

Something you might additionally consider is a SIGCONT signal handler since pausing a program in a shell will likely cause the shell to turn ICANON back on, severely screwing up your program:
Code:

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


struct termios old_settings, new_settings;

void exit(int);

void cont_handler(int sSignal)
{
        printf("%s\n", "[continue handler]");
        if (sSignal == SIGCONT)
        if (tcsetattr(STDIN_FILENO, TCSAFLUSH, &new_settings) < 0) exit(1);
        printf("%s\n", "[press esc to exit]");
}

void term_handler(int sSignal)
{
        printf("%s\n", "[termination handler]");
        if (sSignal == SIGTERM)
        if (tcsetattr(STDIN_FILENO, TCSAFLUSH, &old_settings) < 0) exit(1);
        exit(0);
}



main()
{
        if (tcgetattr(STDIN_FILENO, &old_settings) < 0) return 1;

        new_settings = old_settings;
        new_settings.c_lflag &= ~ICANON;
        new_settings.c_lflag &= ~ECHO;

        if (tcsetattr(STDIN_FILENO, TCSAFLUSH, &new_settings) < 0) return 1;

        signal(SIGCONT, &cont_handler);
        signal(SIGTERM, &term_handler);

        int value;

        printf("%s\n", "[press esc to exit]");

        while ((value = getchar()) != EOF && value != 0x001b)
        printf("read: %c [0x%.4x]\n", (char) value, value);

        if (tcsetattr(STDIN_FILENO, TCSAFLUSH, &old_settings) < 0) return 1;

        printf("%s\n", "[normal exit]");
        return 0;
}

To see what I mean, run the program above and after typing a few chars (in a Bash shell) press [Ctrl]+Z and then type fg. Now compile with the red line commented out and do the same thing.

Note that the SIGTERM handler won't catch a [Ctrl]+C press, which generates a SIGKILL signal. Luckily Bash will reset to canonical mode itself, but it's polite to have the SIGTERM handler in there anyway.

Take a look at tcgetattr, struct termios, and signal in the libc infopages for a whole lot more info on this.
ta0kira

daYz 07-25-2007 02:51 PM

Thanks ta0kira.

I will take a look at this.

Regards,

Ben

haxpor 07-26-2007 02:39 AM

ํAs 95se said, the 'enter' key is also stored in the input-buffer so when the second call of getchar() come to play, it will be skipped. You can fix this by call fflush(stdin) -which means clear the input-buffer out, placing this function between the 2 calls.

jlliagre 07-26-2007 03:10 AM

Avoid fflush(stdin) or any input stream. The behaviour of such a command is undefined according to the C standard.

http://www.iso-9899.info/wiki/Implementation

daYz 07-26-2007 08:02 AM

I have looked at cooked mode and I have tried the tcflush function, but I cannot get it working. Can someone please provide working example code for me please, and explain what is happening?

I want someone to be able to enter a character whereafter he should use the enter key to enter the value, and I want to do this twice in a row like this:

Code:

#include <stdio.h>

main()


char a[] = "Please enter the character a\n\n";
printf("%s", a);

getchar();


char b[] = "Please enter the character b\n\nr";
printf("%s", b);

getchar();

return 0;

}


jlliagre 07-26-2007 08:12 AM

if you want the user to press the enter key after each character, then you can stay in cooked mode. Just call getchar() twice, one for the actual character and the second one to pick the return.

daYz 07-26-2007 08:47 AM

Great! Thanks jlliagre.

Salut

Ben

daYz 07-26-2007 03:23 PM

Quote:

Originally Posted by 95se
Given your rather short post, I can only guess that you don't realize that the new line entered when you press return is a character as well and that it is what the second getchar is returning. If this is not what your talking about, we're going to need a short example (ie. input, expected output, actual output) or something, because it should work otherwise.

Is '\n' the only character that gets entered when pressing the enter key? I always thought it where both '\r' and '\n'.

ta0kira 07-26-2007 04:30 PM

Quote:

Originally Posted by daYz
Is '\n' the only character that gets entered when pressing the enter key? I always thought it where both '\r' and '\n'.

Depends on the terminal. This can be controlled with tcsetattr, though.

I would just use gets to obtain an entire line, then strlen it and use the first character if it's longer than 3. Using 2 getchars in non-canonical mode won't do what you want. Whether the input be a then [Enter] or a then [Backspace] you will still have an uncontrolled input operation.
ta0kira


All times are GMT -5. The time now is 03:10 PM.