what is the use of getchar() in following program

92 views Asked by At
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>

#define NUM_DAYS_IN_WEEK 7


typedef struct
{
    char *acDayName;   
    int iDate;        
    char *acActivity;   
}DAYTYPE;

void fnFreeCal(DAYTYPE *); 
void fnDispCal(DAYTYPE *);
void fnReadCal(DAYTYPE *); 
DAYTYPE *fnCreateCal();

int main() 
{
    // Create the calendar
    DAYTYPE *weeklyCalendar = fnCreateCal();

    // Read data from the keyboard
    fnReadCal(weeklyCalendar);

    // Display the week's activity details
    fnDispCal(weeklyCalendar);

    // Free allocated memory
    fnFreeCal(weeklyCalendar);

    return 0;
}

DAYTYPE *fnCreateCal() 
{
    DAYTYPE *calendar = (DAYTYPE *)malloc(NUM_DAYS_IN_WEEK * sizeof(DAYTYPE));

    
    for(int i = 0; i < NUM_DAYS_IN_WEEK; i++) 
    {
        calendar[i].acDayName = NULL;
        calendar[i].iDate = 0;
        calendar[i].acActivity = NULL;
    }

    return calendar;
}

void fnReadCal(DAYTYPE *calendar) 
{
    char cChoice;
    for(int i = 0; i < NUM_DAYS_IN_WEEK; i++) 
    {
        printf("Do you want to enter details for day %d [Y/N]: ", i + 1);
        scanf("%c", &cChoice); 
        getchar();
        
        if(tolower(cChoice) == 'n')
            continue;
        
        printf("Day Name: ");
        char nameBuffer[50];
        scanf("%s", nameBuffer);
        calendar[i].acDayName = strdup(nameBuffer);  


        printf("Date: ");
        scanf("%d", &calendar[i].iDate);

        
        printf("Activity: ");
        char activityBuffer[100];
        scanf(" %[^\n]", activityBuffer); 
        calendar[i].acActivity = strdup(activityBuffer); 

        printf("\n");
        getchar();      
    }
}


void fnDispCal(DAYTYPE *calendar) 
{
    printf("\nWeek's Activity Details:\n");
    for(int i = 0; i < NUM_DAYS_IN_WEEK; i++) 
    {
        printf("Day %d:\n", i + 1);
        if(calendar[i].iDate == 0)
        {
            printf("No Activity\n\n");
            continue;
        }
        
        printf("  Day Name: %s\n", calendar[i].acDayName);
        printf("  Date: %d\n", calendar[i].iDate);
        printf("  Activity: %s\n\n", calendar[i].acActivity);
    }
}

void fnFreeCal(DAYTYPE *calendar) 
{
    for(int i = 0; i < NUM_DAYS_IN_WEEK; i++) 
    {
        free(calendar[i].acDayName);
        free(calendar[i].acActivity);
    }
    free(calendar);
}

This is a program to Declare a calendar as an array of 7 elements (A dynamically Created array) to represent 7 days of a week. Each Element of the array is a structure having three fields. The first field is the name of the Day (A dynamically allocated String), The second field is the date of the Day (A integer), the third field is the description of the activity for a particular day (A dynamically allocated String). Write functions create(), read() and display(); to create the calendar, to read the data from the keyboard and to print weeks activity details report on screen. There are two getchar() methods in this program, why is getchar() necessary.

1

There are 1 answers

3
John Bode On

It's being used to consume the trailing newline from the previous input.

Unlike the %s and %d conversion specifiers, the %c and %[ conversion specifiers don't skip over leading whitespace, so they can erroneously pick up a newline from the previous input. Without the getchar call, the second time through the loop the scanf("%c", &cChoice); call will read the newline from the previous activity input and assign it to cChoice, throwing off your remaining inputs.

There is a better way to deal with this, though. You can use a leading blank in the format string:

scanf( " %c", &cChoice );

That leading blank will consume any leading whitespace, so you don't need a separate getchar call before it.