-2

I am trying to read characters one at a time and convert them to int in a cumulative manner. If the user enters a character other than a number i start the whole process all over again. When i run this code, the code below getchar() gets executed only after i press the enter key instead of executing with every key press. In brief, instead of taking one character at a time, it takes a string terminated with enter as input and then reads one character at a time from the input string and executes the while loop. I am pretty sure it has something to do with the \n in the printf statements. My c code:

    char* input=malloc(0);
    char c; 
    int count=0;
    int a;
    int b;  
    errno=0;
    printf("\nEnter two numbers a and b\n");

    while(1){
        count++;
        printf(":Count:%d",count);
        c=getchar();
        printf("\n::%c::\n",c);
        if(c=='\n')
            break;
        input=realloc(input,count);
        input[count-1]=c;
        errno=0;
        a=strtol(input,NULL,10);
        printf("\nNUMber::%d\n",a);
        if (errno == ERANGE && (a == LONG_MAX || a == LONG_MIN)){
            printf("\nLets start over again and please try entering numbers only\n");
            count=0;
            input=realloc(input,0);     
        }
    }
thunderbird
  • 2,715
  • 5
  • 27
  • 51
  • That's because of the fact that `getchar()` is terminal io settings dependent. Since most terminals have line buffering enabled, it waits until you press enter. Using `termios.h`, you can disable that. `getch()` is windows-only. Also, why `realloc(, 0)`? Why not just `free()`?. Also, `malloc(0)` is undefined behaviour. It can return NULL, or SEGFAULT. – cyphar Oct 11 '13 at 11:38
  • "getch() working abnormally" - I doubt. A decent standard library implementation hardly has bugs. –  Oct 11 '13 at 11:40
  • mybad read the title again..its getchar() – thunderbird Oct 11 '13 at 11:42
  • malloc(0) does no harm at all. – thunderbird Oct 11 '13 at 11:45
  • @H2CO3 everything ever programmed has bugs. – thunderbird Oct 11 '13 at 11:49
  • @thunderbird I didn't write "it doesn't have bugs". Make the distinction. The world is not black and white. –  Oct 11 '13 at 11:49
  • `malloc(0)` does no harm but passing the returned pointer (or NULL) to `strtol` (as parameter `input`) does – msam Oct 11 '13 at 11:54
  • @msam its just my style of coding..whenever i use realloc on a variable I initialize it with malloc(0)..i cant see how its wrong? – thunderbird Oct 11 '13 at 12:02
  • if `count` is 0 your `realloc` will free `input`, and set input to either NULL or a freeable but undeferencable pointer which you then pass to `strtol` – msam Oct 11 '13 at 12:08
  • @msam count is never zero...count++ is at the very beginning of the loop. – thunderbird Oct 11 '13 at 12:17

2 Answers2

1

That's because of the fact that getchar() is terminal io settings dependent. Since most terminals have line buffering enabled, it waits until you press enter. Using termios.h, you can disable that. getch() is windows-only.

Here is some code to do what getch() does in Linux.

#include <termios.h>

char getch(void) {
    /* get original settings */
    struct termios new, old;
    tcgetattr(0, &old);
    new = old;

    /* set new settings and flush out terminal */
    new.c_lflag &= ~ICANON;
    tcsetattr(0, TCSAFLUSH, &new);

    /* get char and reset terminal */
    char ch = getchar();
    tcsetattr(0, TCSAFLUSH, &old);

    return ch;
}

Also, why realloc(blah, 0)? Why not just free(blah)?. Also, malloc(0) is undefined behaviour. It can return NULL or give a unique pointer. Same with realloc(blah, 0).

cyphar
  • 2,840
  • 1
  • 15
  • 25
0

just use:

#include <stdlib.h>

char getch()
{
char c; // This function should return the keystroke

system("stty raw");    // Raw input - wait for only a single keystroke
system("stty -echo");  // Echo off

c = getchar();

system("stty cooked"); // Cooked input - reset
system("stty echo");   // Echo on - Reset

return c;
}
Nandakumar Edamana
  • 770
  • 1
  • 4
  • 10
  • `system()` is unsafe. What if someone replaces the `stty` binary with something evil? Or they just put an evil binary in your current directory, and changed your path to `.:/bin:/usr/bin`? – cyphar Oct 12 '13 at 01:08