0

I have this code, which I expect from to read a single character from user, then re-print it, then realloc'ing new memory to store the next character that user will enter; all this repeating until the user enters the '1' character. However, my program does nothing until the user presses 'return', then echoes back the entire string. Why does it behave like this?

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

int main()
{
    char *s = (char *)malloc(sizeof(char));
    int i = 1 ;
    do
    {
        scanf(" %c",s+i-1);
        printf("%c" , *(s+i-1));
        i++ ;
        s = (char *)realloc(s , sizeof(char)*i);
    }while(*(s+i-1) != '1');
    printf("\n\n %s" , s);
    return 0;
}

This is what I expect:

h // input from user
h // the output
w // input from user
w // output from user

But this is what I get:

what // input from user
what // output 

I tried to replace scanf by getchar, but that doesn't help.

Søren Debois
  • 5,598
  • 26
  • 48
hbak
  • 1,333
  • 3
  • 10
  • 22
  • 1. Why are you using casts on the `malloc`? 2. Just `malloc` a reasonable amount in the first place (say 2Ks) and avoid the realloc. – Ed Heal Mar 23 '14 at 08:21
  • On which operating system? – Basile Starynkevitch Mar 23 '14 at 08:21
  • your printing the string pointed to by `s` which is why you get the result. `h` `h` `w` `w` are all stored in the same string. – tesseract Mar 23 '14 at 08:22
  • 2
    `stdin` buffers characters until the user presses the `enter` key. Then it gives the whole line to your program at once. This allows the user to edit the line before submitting it. You have to change the terminal settings if you want one character at a time. – user3386109 Mar 23 '14 at 08:22
  • 1
    It looks like you want to use [GNU readline](http://cnswww.cns.cwru.edu/php/chet/readline/rltop.html) – Basile Starynkevitch Mar 23 '14 at 08:24
  • @EdHeal , i want to allocate amount of memory equal the size of string input , – hbak Mar 23 '14 at 08:25
  • @BasileStarynkevitch , Linux , ubunto – hbak Mar 23 '14 at 08:26
  • I have tried to enter about 50 character at first time , and it re print it ! , and note that i have allocated just 1 byte !! how this happened! – hbak Mar 23 '14 at 08:29
  • @Learner - Why? Most (all?) have paging and therefore the OS will allocate a page anyway. Anyway what is a 2K of virtual memory when a couple of Gbs are in the loop – Ed Heal Mar 23 '14 at 08:33
  • @EdHeal , i want to understand memory management in c , it seems wared , but this is help me , the problem is not how to get string from input , the problem is how to use memory allocation .. – hbak Mar 23 '14 at 08:36
  • 1
    @Learner - This is OS dependent. malloc will get a chunk of memory from the OS and that size will depend on the OS to make it comfortable. realloc may bite into that memory or require malloc to ask again from a bigger chunk. Therefore ask malloc to give you a reasonable amount of memory for the task in hand and save on the function calls – Ed Heal Mar 23 '14 at 08:41
  • @EdHeal , what is the lower limit of " reasonable amount of memory" , or This is OS dependent . i understand from your previous comment , if we have a small program like mine , we can just depend on Page that OS allocate for us , and we can just define a pointer from each type , and access the memory (our page) , without allocating or defining variable ? – hbak Mar 23 '14 at 08:47
  • @Learner - How about 1024 bytes. That is a lot of typing – Ed Heal Mar 23 '14 at 08:52
  • possible duplicate of [C/C++: Capture characters from standard input without waiting for enter to be pressed](http://stackoverflow.com/questions/421860/c-c-capture-characters-from-standard-input-without-waiting-for-enter-to-be-pr) – n. m. could be an AI Mar 23 '14 at 09:11

3 Answers3

1

Input is buffered and won't be delivered to your program until the user hits return. See this question or this question.

Your use of malloc/realloc has nothing to do with it.

Community
  • 1
  • 1
Søren Debois
  • 5,598
  • 26
  • 48
  • Moreover, stdout is buffered too. – Marian Mar 23 '14 at 08:31
  • First of all , thanks for editing , secondly , i have tried to enter about 50 character at first time , and it re print it ! , note that i have allocated just 1 byte !! how this happened ? – hbak Mar 23 '14 at 08:33
0

That is because the standard output stream stdout is line-buffered. This means that output won't appear on the screen until a newline '\n' is output or the buffer is full at which the buffer is flushed. Also, you should not cast the result of malloc or realloc. You should also check for the result of malloc or calloc for NULL.

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

int main(void) {
    char *s = malloc(sizeof *s);
    if(s == NULL) {
        printf("not enough memory to allocate\n");
        return 1;
    }
    int i = 0;
    char *temp;
    do {
        scanf("%c", s + i);
        printf("%c\n", *(s + i));
        i++;
        temp = s;
        s = realloc(s, i * sizeof *s);
        if(s == NULL) {
            printf("not enough memory to allocate\n");
            s = temp;
            // handle it
            // break;
        }
    } while(*(s + i) != '1');
    printf("%s\n", s);

    // after you are done with s, free it
    free(s);

    return 0;
}
ajay
  • 9,402
  • 8
  • 44
  • 71
  • You said "you should not cast the result of malloc or realloc" , could you tell me why ? – hbak Mar 25 '14 at 18:19
  • 1
    @Learner That's because there's no benefit and it can lead to bugs if you forget to include the header `stdlib.h`. Read this for details http://stackoverflow.com/questions/605845/do-i-cast-the-result-of-malloc – ajay Mar 25 '14 at 18:34
0

stdin buffers characters until the user presses the enter key , so it will not deal , with single character.

Super Learner
  • 151
  • 13