C beginner: problem with basic input

I am a beginner. I am learning c. The problem occurs when I have more than one getchar(). (or getc or fgetc etc...) When the program reaches the next getchar (or getc or fgetc..) it seems like it just skips over it, you type something, hit <enter> and its keeps going, skipping over the next getchar(). I tried to figure it out on my own and I learned that its retaining the <enter> keystroke and putting it as the first character of the next variable (or buffer) I intended to use.

fflush() and fpurge() wont work, no matter what parameters I use,what combinations, or where I place them in the program. fflush(stdout) wont flush the '\n', I heard its not a good idea to fflush(stdin), and fpurge(stdin) is killing the buffer before I can use it. gcc returns exact same results. Also, I compiled it on other platforms with different compilers.....I still get the same thing.

I have a "go-arounds" but I would like to know whats really going on.

Here...check this out....
Code:
//-----------------------  testbuf.c ----- cc -Wall -g -o testbuf testbuf.c
#include <stdio.h>

void myrout()
{
   char a;

   printf("\nEnter another key : ");
   a = getchar();
   printf("\nYou entered : %c\n",a);
}

int main()
{
   char b;

   printf("\nEnter a key : ");
   b = getchar();
   printf("\nYou entered : %c\n",b);
   myrout();

   return 0;
}

Can someone break this down for me? Maybe from a stdin, stdout kind of point of view?

thanks
 
getchar gets a single char. If for that first input, you are entering say "A" followed by "ENTER", then the 2nd getchar is picking up the "ENTER".
As an experiment enter two characters in the first prompt, followed by enter. You'll see the 2nd char is picked up by the 2nd getchar.
 
Try this:
Code:
#include <stdio.h>
#include <stdlib.h>
int main(void)
{
    int ch;
    while(EOF != (c = getchar()))
    {
        (void) putchar(ch);
    }
    return (EXIT_SUCCESS);
}
The above program copies input to stdout and stops at the first occurrence of EOF (a non printable character whose purpose is to signal the end of data stream). You can type EOF using CTRL+D on *BSD & Linux and CTR+Z on Windows. It should crystal clear what getchar does: it just read a character from stdin buffer until the EOF. You may find helpful the manpage for getchar.
I would like to make notice to OP few things:
- There are only two correct ways for writing main() in mainstream environments:
N.1
Code:
int main(void)
{
}
N.2
If you need commando line arguments
Code:
int main(int argc, char **argv)
- It is a good practice returning EXIT_SUCCESS upon success and EXIT_FAILURE upon failure because by doing so you make your code more portable and correct. 0 indicates that your program terminated successfully on most operating systems, but for example 0 is an error code on VMS, so you should let the macros EXIT_SUCCESS and EXIT_FAILURE take care of the return value.
- printf is heavy and deprecated. Use puts or fputs when you don't need to print data but just messages. If you have a C99 compliant compiler (and Clang 3.8 installed by default in FreeBSD 11 is one of those compilers) use snprintf + puts/fputs for printing data. When using C99 limit yourself to the strictly necessary features of that standard and moreover do not use VLAs!
Finally i suggest you to read "The C programming language" 2nd Edition by the authors of the language, Dennis Ritchie and Brian Kernighan.
 
getchar gets a single char. If for that first input, you are entering say "A" followed by "ENTER", then the 2nd getchar is picking up the "ENTER".
As an experiment enter two characters in the first prompt, followed by enter. You'll see the 2nd char is picked up by the 2nd getchar.

I think you nailed it. What do other people do in this situation?
 
...I would like to make notice to OP few things:
- There are only two correct ways for writing main() in mainstream environments:...
Funny you brought up K&R, I was actually thinking that's where I learned that for main you don't need the void, I dont know about VMS compilers though. The program I posted compiles fine. I used the default cc and gcc from FreeBSD 11, I used clang after I read your post, I tried it on windows with visual c, and some freeware called Pelle's C, and tried it on Debian Linux again the default c compiler. Nope, no warnings, actually, no warnings, no C99 messages, no "deprecated please use messages"...
I need to look into this a little more...

- It is a good practice returning EXIT_SUCCESS upon success and EXIT_FAILURE upon failure because by doing so you make your code more portable and correct. 0 indicates that your program terminated successfully on most operating systems, but for example 0 is an error code on VMS, so you should let the macros EXIT_SUCCESS and EXIT_FAILURE take care of the return value.
but...I LIKE what you are saying here, thanks., are they actually macros though?

- printf is heavy and deprecated. Use puts or fputs when you don't need to print data but just messages. If you have a C99 compliant compiler (and Clang 3.8 installed by default in FreeBSD 11 is one of those compilers) use snprintf + puts/fputs for printing data. When using C99 limit yourself to the strictly necessary features of that standard and moreover do not use VLAs!
not finding anything about this....

Finally i suggest you to read "The C programming language" 2nd Edition by the authors of the language, Dennis Ritchie and Brian Kernighan.
This is still around...wow that takes me back :)....again, Thank you.
 
use snprintf + puts/fputs for printing data
No, just continue using printf(3) if you need to do this. This doesn't make any sense to me. Where is this recommended?

Modern compilers replace calls like printf("hello\n") with puts("hello") automatically.
However, I don't agree that...
- There are only two correct ways for writing main() in mainstream environments:
Funny you brought up K&R, I was actually thinking that's where I learned that for main you don't need the void, I dont know about VMS compilers though. The program I posted compiles fine.
The C99 and C11 standards recommend the two variants that ubuntumate describes. Since this is C you're of course free to ignore this ;)

Using int main() means that you won't get an error message if you do something like this in your program:
Code:
main("Hello", "I", "accept", "anything", 42);
int main(void) is a hint to the compiler that main takes no parameters and that it should give you an error if you write bad code like this.
What do other people do in this situation?
Read whole lines e.g. pkg uses getline(3) for its y/n prompts.

are they actually macros though?
Yes, they are #define'd in stdlib.h and thus are macros.
 
Regarding main() write a template like this one:
Code:
/*******************************************************************************
** PROGRAM...: 
** AUTHOR.....: 
** LICENSE....: 
** DATE.......:
** VERSION...: 1.0
** DESCRIPTION:
** NOTES.......:
*******************************************************************************/
#include <stdio.h>
#include <stdlib.h>

int main(void)
{
   return (EXIT_SUCCESS);
}
/******************************************************************************
* EOF: 
******************************************************************************/
and forget this question.

You can ignore for now the advice regarding snprintf+puts because it is a practice coming from realtime embedded systems (i mean microntrollers, not in the common and wrong sense of small devices like smartphones) where knowing exactly how long a task takes to be completed is critical. See the following thread for a quick answer on this topic
http://stackoverflow.com/questions/...tween-sprintf-and-printf-for-microcontrollers
I recommend to make use of SPLint and similar software and the adoption of a strict coding standard like MISRA/C which is not a prerogrative of senior safety-critical embedded systems developers. All can benefit from those standards

Modern compilers are not smarter than who wrote them and we, as programmers, should not rely too much on them. I always prefer calling puts explicitly, writing x << 1 instead of x*2 etc The fact that all compilers tried by Sixto Areizaga did throw no warnings on int main() is a confirm of what i stated above: compilers are not reliable, at least Clang, GCC and the other safety-critical non-certified ones. As i have been taught by extremely educated person in this field,the rule of thumb is to always inspect the output of the compiler.



Sorry for my bad english, i hope to improve over the time and to be understood by you mother tongues.
Ubuntumate
 
Back
Top