Hey, I have a problem taking input from the terminal. I need to read an integer first, then a string. But when I press enter after entering the integer, the string doesn't take any input. Yes, I did try using a fflush(stdin) between the 2 inputs, still doesn't work. I am aware of the difference between gets and fgets and tried both, still doesn't work.

This is the code I am using. Please have a look.

#include<stdio.h>
#include<malloc.h>

int id = 0;
char* name;

int main(void)
{
 name = (char*)malloc(200 * sizeof(char));

 printf("\nEnter id ");
 scanf("%d",&id);

 fflush(stdin);
 
 printf("\nEnter name ");
 gets(name);

 printf("\n[%s] is [%d] years old",name,id);
 printf("\nAscii of name = %d",*name);

 return 0;
}

I tried printing the string and it prints 0 as the first character's ascii, Why is that. I would have expected that since, I am pressing enter, the string is taken as enter, and the ascii would read 13(ascii of Enter).

Thanks,
Tubby.

Yes, I did try using a fflush(stdin) between the 2 inputs, still doesn't work.

You're making the assumption that fflush(stdin) is clearing the input stream, which isn't a safe assumption. Technically it's undefined behavior to call fflush() on an input stream. As a quick test, replace the fflush(stdin) line with this one:

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

Also check to see if malloc() returned a null pointer. It would likely crash if that were the case, but you might otherwise get some odd behavior.

Do those two things and come back if they don't have any difference. There are a number of things that could go wrong with this program, but I don't want to overwhelm you with possibilities. :)

You're making the assumption that fflush(stdin) is clearing the input stream, which isn't a safe assumption. Technically it's undefined behavior to call fflush() on an input stream. As a quick test, replace the fflush(stdin) line with this one:

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

Also check to see if malloc() returned a null pointer. It would likely crash if that were the case, but you might otherwise get some odd behavior.

Do those two things and come back if they don't have any difference. There are a number of things that could go wrong with this program, but I don't want to overwhelm you with possibilities. :)

deceptikon, that really was very very good :)
yes it worked.But I would like to know, what are the other things that make the code 'unclean'. Thanks once again. :)

deceptikon, Also please tell me why the ascii printed reads 0.
As i said, I would have expected it to read 13 because that's the ascii value of enter.

Thanks.

But I would like to know, what are the other things that make the code 'unclean'.

  • Global variables where they're unnecessary.
  • Using malloc() when it isn't justified.
  • malloc.h isn't the correct header for malloc(), it should be stdlib.h.
  • No error checking of malloc() or input functions.

I also think mixing formatted and unformatted input is unclean because it forces you to do stuff like flushing the input stream, but that's a personal opinion. It's easier to use fgets() for all input and then parse it to get non-string types:

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

int* fgeti(int* var, FILE* strm)
{
    char buf[BUFSIZ];
    
    if (fgets(buf, sizeof buf, strm) &&
        sscanf(buf, "%d", var) == 1)
    {
        return var;
    }
    
    return NULL;
}

int main(void)
{
    char name[200];
    int id;
    
    if ((printf("Enter id: "), fgeti(&id, stdin)) &&
        (printf("Enter name: "), fgets(name, sizeof name, stdin)))
    {
        printf("\n[%s] is [%d] years old", name, id);
        printf("\nAscii of name = %d", *name);
    }

    return 0;
}

Also please tell me why the ascii printed reads 0.

The only reason I can think of is you typed the enter key and nothing for the name. gets() doesn't store a new line character in the string like fgets(), so you're looking at the null character terminator.

deceptikon, that really was very very good :)
yes it worked.But I would like to know, what are the other things that make the code 'unclean'. Thanks once again. :)

Using gets() is a BIG unclean move. See this

Also, changing the value of a variable more than once in a statement, like x = (3 * --x) + x++; x is changed 3 times so there's no telling what the value will be for certain. See this

Those are the two that come up most often.

  • Global variables where they're unnecessary.
  • Using malloc() when it isn't justified.
  • malloc.h isn't the correct header for malloc(), it should be stdlib.h.
  • No error checking of malloc() or input functions.

I also think mixing formatted and unformatted input is unclean because it forces you to do stuff like flushing the input stream, but that's a personal opinion. It's easier to use fgets() for all input and then parse it to get non-string types:

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

int* fgeti(int* var, FILE* strm)
{
    char buf[BUFSIZ];
    
    if (fgets(buf, sizeof buf, strm) &&
        sscanf(buf, "%d", var) == 1)
    {
        return var;
    }
    
    return NULL;
}

int main(void)
{
    char name[200];
    int id;
    
    if ((printf("Enter id: "), fgeti(&id, stdin)) &&
        (printf("Enter name: "), fgets(name, sizeof name, stdin)))
    {
        printf("\n[%s] is [%d] years old", name, id);
        printf("\nAscii of name = %d", *name);
    }

    return 0;
}

The only reason I can think of is you typed the enter key and nothing for the name. gets() doesn't store a new line character in the string like fgets(), so you're looking at the null character terminator.

Makes a lot of sense deceptikon. When I replaced gets with fgets as u said, yes, it gave me ascii value 10(ascii of linefeed), and not 0, as in gets. Cool!
Will take care of the other mistakes u pointed out from now on.

This article has been dead for over six months. Start a new discussion instead.