1

This is a newbie question. I am new to C programming. I have the following code which does not prompt for 'Name' Onece the 'Age' is entered, it bypass the 'Name section.

#include <stdio.h>

int main()
{
    char name[30],ch;
    int age;

    printf("Enter age : ");
    scanf("%d", &age);

    int i=0;
    printf("Enter name: ");

    while((ch = getchar())!='\n')
    {
        name[i]=ch;
        i++;
    }
    name[i]='\0';

    printf("Name: %s\n",name);
    printf("Age : %d\n", age);
    return 0;
}

After reading first prompt it bypass the second prompt which is using getchar() function. But if I change the order of prompt to ask for 'Name' first and then 'Age' it works fine.

The working code.

#include <stdio.h>

int main()
{
    char name[30],ch;
    int age;

    int i=0;
    printf("Enter name: ");

    while((ch = getchar())!='\n')
    {
        name[i]=ch;
        i++;
    }
    name[i]='\0';

    printf("Enter age : ");
    scanf("%d", &age);

    printf("Name: %s\n",name);
    printf("Age : %d\n", age);
    return 0;
}

My coding IDE is CodeBlock and my compiler is GNU C Compiler (mingw32-gcc.exe)

Please help me to breakthrough.

Muneer
  • 7,384
  • 7
  • 38
  • 62
  • 1
    From memory, `scanf("%d ")` (with a space) will read whitespace (including the \n on input) – sje397 Jan 01 '14 at 13:04
  • Dear all, may be it is duplicate, I am newbie in c. I am confused in this. Thats y i opened a new question. try to help me understand please. – Muneer Jan 01 '14 at 13:28
  • bhai just add a getchar() above the while loop, which will take the extra '\n' – APan Jan 01 '14 at 13:30
  • @BlueBird If you have a look at the answers on duplicates, you will understand it. Also, documentation. (And don't use `scanf()`, it's insane, evil and counter-intuitive. Use `fgets()` instead.) –  Jan 01 '14 at 13:52
  • Yes, I used fgets() function. It seems works fine. – Muneer Jan 02 '14 at 05:39

2 Answers2

2

A few improvements/advices to the code in the question:

  1. the type of the return value of getchar() is int, so the type of ch also should be int
  2. you could (and should, I believe) use format %s to read the name, this is easier and the leading white spaces in the input stream would not be a problem
  3. the user of the code could give a name which contains more than 30 characters, and this input could crash your program, so you should protect your code for this possibility. You have two options:

    a. use format '%29s" to read the name
    b. change the definition of name to char *name, read it by scanf("%ms", &name);, and call free(name); after you do not need it anymore

Here is an example, in which the name can be very long and can include spaces:

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

int
main(int argc, char *argv[])
{
    char *name;
    int age;

    printf("Enter name: ");
    scanf("%m[^\n]", &name);

    printf("Enter age: ");
    scanf("%d", &age);

    printf("Name: %s\n", name);
    printf("Age : %d\n", age);

    free(name);

    exit(EXIT_SUCCESS);
}

And here is a run of it:

$ ./a.out 
Enter name: a very looooooooooooooooooooooooooooooooooooooooooooooong name
Enter age: 12
Name: a very looooooooooooooooooooooooooooooooooooooooooooooong name
Age : 12
Lee Duhem
  • 14,695
  • 3
  • 29
  • 47
  • hi leeduhem, thanks for your explanation. I tried using scanf() but it breaks once there is a space. Any way, I can see an aditional m in your code scanf("%ms", &name) . Actually what is that mean by "%ms" ? it will read along with the space? – Muneer Jan 02 '14 at 05:38
  • @BlueBird The `m` modifier is a POSIX.1-2008 extension to C89/C99, which means `scanf()` itself will allocate (through `malloc()`) the needed space to store the input string, and the caller is responsible to free this space by `free()`. You can check out [scanf](http://pubs.opengroup.org/onlinepubs/9699919799/functions/scanf.html) and `scanf(3)` for future details. – Lee Duhem Jan 02 '14 at 06:54
  • @BlueBird To read everything except newline in a line, you can you using the format `%m[^\n]`. I will add a example in my above answer. – Lee Duhem Jan 02 '14 at 06:58
1

In first code the \n character left behind by the scanf is read by getchar. This makes the condition (ch = getchar())!='\n' in while loop false and the loop body never get executed.
You need to consume that \n character which comes up to the buffer along with the age you entered on pressing Enter key.
Putting the statement

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

after the scanf will consume all of the newline characters.

Your second code is working fine because %d skips white-space characters unlike %c specifiers.

haccks
  • 104,019
  • 25
  • 176
  • 264