3

Okay so i'm trying to make a "read character" function that would only take upper or lower-case letters, not accents (i'm french so it's important with french keybords) and return it upper-cased. For that i made another source file for the readcharacter function:

char readCharacter()
{
    char character;

    do
    {
        printf("Please enter a letter without accents and hit 'enter': ");

        character = getchar();
        while(getchar() != '\n');

        printf("\n");

        character = toupper(character); //Upper-case if lower case
    } while(((character < 65)||(character > 90)));
    return character;
}

Here's my main:

#include "main.h"
int main(void)
{
    char MyLetter = readCharacter();
    char MyLetter2 = readCharacter();
    printf("%c\n%c\n", MyLetter, MyLetter2);
}

My problem is, i got this as output:

S
l
Please enter a letter without accents and hit 'enter': 
Please enter a letter without accents and hit 'enter':
S
L

Why don't i get this?

Please enter a letter without accents and hit 'enter':S 
Please enter a letter without accents and hit 'enter':l
S
L

Don't know if this is relevant, but my IDE is eclipse and compiler is MinGW (gcc?) Sorry for bad english and/or bad coding... i've just started coding... Thx!

  • 3
    Please note that [`getchar`](http://en.cppreference.com/w/c/io/getchar) actually returns an `int`. – Some programmer dude Aug 31 '17 at 09:11
  • 1
    As for your problem, can you please elaborate on it? You show the output you get, but what output did you *expect*? Have you tried to step through your code in a debugger? Perhaps you should take some time to read [How to debug small programs](https://ericlippert.com/2014/03/05/how-to-debug-small-programs/) by Eric Lippert. – Some programmer dude Aug 31 '17 at 09:12
  • Edited the expected output :) – Jules Raschilas Aug 31 '17 at 09:13
  • And yes i know but isn't an int actually also a char? Thx to the ascii table? – Jules Raschilas Aug 31 '17 at 09:14
  • 3
    A good read on why you should respect the return value type of `getchar()`: https://stackoverflow.com/questions/35356322/difference-between-int-and-char-in-getchar-fgetc-and-putchar-fputc. Long story short, EOF will cause trouble, and some characters might be interpreted as EOF in some cases. And on success `getchar()` and the like return the character value as unsigned char, converted to int. – Ilja Everilä Aug 31 '17 at 09:14
  • @JulesRaschilas A literal character constant like e.g. `'a'` is an `int`. But an `int` it not a `char` (or the opposite). And the distinction of the return type is actually *very* important when you check for end-of-file `EOF`. – Some programmer dude Aug 31 '17 at 09:16
  • The code runs normally when I try it [https://prnt.sc/gfasn6](https://prnt.sc/gfasn6) – campovski Aug 31 '17 at 09:17
  • Also, even when using ASCII please try to avoid [*magic numbers*](https://en.wikipedia.org/wiki/Magic_number_(programming)). If by `60` you mean the character `' – Some programmer dude Aug 31 '17 at 09:18

3 Answers3

4

The problem is that output to stdout (which is used by printf) is line buffered by default. That means the buffered output is only written if there's a newline, the buffer gets full or you explicitly flush it.

Since none of that happens here in your function, the output is simply "delayed" until it is flushed by the newline you print in the main function.

There are two solutions:

  1. Either add a newline at the end of the string you print in the readCharacter function;
  2. Or call fflush(stdout) to flush the buffers after the printf call.
Some programmer dude
  • 363,249
  • 31
  • 351
  • 550
  • Okay, i added the fflush(stdout) and it worked just fine, thx everybody and sorry for reposting existing questions: i didn't lokk for them with the approprite keywords i think! – Jules Raschilas Aug 31 '17 at 09:45
3

You need to be careful with interactive programs that do not print \n, because the output may remain buffered for longer than you need.

Add a call to fflush(stdout) after printf, or add \n at the end of the string that you print to fix this problem.

Note that pressing Ctrl+D (Ctrl+Z on Windows) turns the loop that waits for '\n' while(getchar() != '\n'); into an infinite loop.

Also note that you can avoid numeric comparisons to character codes, such as character < 65, by using !isupper(character).

Sergey Kalinichenko
  • 675,664
  • 71
  • 998
  • 1,399
1

Your algorithm for filtering the '\n' is wrong and you possibly need to flush the output buffer after printf.

You want this:

char readCharacter()
{
  char character;

  do
  {
    printf("Please enter a letter without accents and hit 'enter': ");

    fflush(stdout);  // may be not nessesary depending on your platform

    do
    {
      character = getchar();
    }
    while (character == '\n');

    printf("\n");

    character = toupper(character); //Upper-case if lower case
  } while ((character < 'A') || (character > 'Z'));

  return character;
}

I also replaced the magic numbers 65 and 90 by 'A' and 'Z' which is more readable because if clearly shows your intention.

Jabberwocky
  • 40,411
  • 16
  • 50
  • 92
  • Hi, thx for the answer! In fact i don't understand very well the line i made myself: while(getchar() != '\n');, i think it has to do with the buffer-thing that everybody seems to know about, except they NEVER talk about it in the tutorial i follow... Could you elaborate on why do { character = getchar(); } while (character == '\n'); is different? – Jules Raschilas Aug 31 '17 at 10:00