2

Here is how the code's written.

int main()
{   
    char enteredName[30];
    char stringNum[4];
    char continueLetter = 0;
    int continueProgram = 0;
    int enteredAge;
    int i;

    do
    {
    memset(enteredName,'\0', 30);
    printf("Please enter a name: ");
    fgets(enteredName, 29, stdin);

    printf("\n\nNow please enter your age: ");
    fgets(stringNum, 3, stdin );

    for(i = 0; i < 30; i++)
    {
        if (enteredName[i] == '\n')
        {
            enteredName[i] = '\0';
            break;
        }
    }

    for(i = 0; i < 4; i++)
    {
        if (stringNum[i] == '\n')
        {
            stringNum[i] = '\0';
            break;
        }
    }

    enteredAge = atol(stringNum);
} while();

When I run through the loop a second time, I'm not able to enter a new name into the char array, it just goes to the next prompt (the age). Unless this issue involves linked lists, the problem seems to be with something else. Could you help me find the error? Thanks!

Adrian Panasiuk
  • 7,249
  • 5
  • 33
  • 54
GemToughy
  • 21
  • 1
  • 3
  • Thank you for your help people, and I must apologize, but this wasn't the entire piece of code; it was a part that I thought had the main issue. The remaining code involved a char variable for "Continuing the program with a Y/N". It did not check for the '\n' like my 'for loops' did, so I just fixed it with a simple fflush. Again, thanks for the help, and have a good day! – GemToughy Jun 21 '13 at 19:34
  • Note that you should check the return value from `fgets()` after every use of it. – Jonathan Leffler Jun 23 '13 at 06:29

4 Answers4

1

Your second fgets call leaves characters (specifically the newline) waiting to be read from stdin if you enter a two digit age.

Increase the length parameter to match the array size:

fgets(stringNum, 4, stdin);

Or better:

fgets(stringNum, sizeof stringNum, stdin);

You probably want to do the same for enteredName.

From the fgets(3) man page:

The fgets() function reads at most one less than the number of characters specified by size from the given stream and stores them in the string str.

You don't need to reserve the extra array entry for the null-terminator like you're doing - fgets will handle that correctly on its own.

Carl Norum
  • 219,201
  • 40
  • 422
  • 469
1

The problem is,you are not flushing the input buffer that is why the fgets() takes you directly to the second prompt asking age.This is common problem encountered,just add fflush(stdin);//my compiler supports itafter fgets();.Here is the code which has worked for me hope it works for you too :

EDIT: There is one very useful post providing information regarding fflush().As it is described that fflush is basically meant to be called to an output stream.Although some compilers provide support for flushing stdin,this is considered an undefined behavior.While having another look at the program, I found out that using sizeof can work wonders and is valid, So, I have modified the program for better. The use of sizeof is also described in one of the answers here.

#include<stdio.h>
#include<stdlib.h>
int main()
{   
    char enteredName[30];
    char stringNum[4];
    int continueProgram=0;
    int i;

   while(continueProgram<3)
      {
        setbuf(stdout,NULL);
    printf("Please enter a name: ");
    fgets(enteredName, sizeof enteredName, stdin);
    printf("\n\nNow please enter your age: ");
    fgets(stringNum,sizeof stringNum, stdin );

   for(i = 0; i < 30; i++)
    {
        if (enteredName[i] == '\n')
        {
            enteredName[i] = '\0';
            break;
        }
    }

    for(i = 0; i < 4; i++)
    {
        if (stringNum[i] == '\n')
        {
            stringNum[i] = '\0';
            break;
        }
    }

    //enteredAge = atol(stringNum);
    continueProgram++;
    }
    return 0;
}
Community
  • 1
  • 1
0decimal0
  • 3,884
  • 2
  • 24
  • 39
  • Thanks dude, that fflush works wonders. Another way I found was just to put a extra getchar at the bottom, but that would've only taken care of one leftover. I'll read up a bit more on this, it's very useful. – GemToughy Jun 21 '13 at 19:24
0

The problem is that you don't know whether the string that has been read contains a newline or not. If it doesn't contain a newline, then this is going to be read by the next call to fgets, leaving an empty string in it. To prevent it, check if the line contains a newline character at the end. If not just read it using getchar() and Voila!!(Note that this solution is valid only to your problem, not in general). This code is to be added after reading the stringNum string.

if(stringNum[strlen(stringNum)-1]!='\n')
{
    getchar();
}

This was happening because, if the age is a double digit, then fgets is going to read until the last digit and not the newline character. So,you need to read it in case the last char is not \n. If the age is a single digit, the the original program works fine.

nitish712
  • 19,504
  • 5
  • 26
  • 34
0

You try this following piece of code:

if(stringNum[strlen(arr)-1]=='\n')
     stringNum[strlen(arr)-1]='\0';
else
     while(getchar()!='\n');

Whenever you enter a two digit age, the newline character which you insert while pressing enter gets stored in the buffer. What this above piece of code is doing is that, it will check whether the last character of your storage is filled with a newline character, if yes, then it will replace it with the null terminator. Else, it will keep reading from the buffer until and unless the newline character is removed from the buffer.

PS: If you are using borland then you will have fflush(stdin) to flush out any extra character from the buffer as indicated by PHlFounder, but if you happen to use gcc then this method is very good.

Also you can create a function or macro for this piece of code and call it every time you need, for eg.

void function(char * arr)
{
        if(arr[strlen(arr)-1]=='\n')
                arr[strlen(arr)-1]='\0';
        else
                while(getchar()!='\n')
}
Biplob Biswas
  • 1,761
  • 19
  • 33