Search code examples
cinputconsolestructure

How to ignore a given console input


My question (as the title suggests) is how to ignore the inputs in the console.

My program will take inputs representing first, middle and last name. For example, stud.name.mdlename should be empty if anyone does not have a middle name, it should be ignored so that it didn't take any input.

// write a program to read and display information of a 
// student using a structure within a structure.
#include <stdio.h>

typedef struct studentName
{
    char frstnme[10];
    char mdlenme[10];
    char lstnme[10];
}Name;
typedef struct studentdob
{
    int dd;
    int mm;
    int yy;
}DOB;
typedef struct studentinfo
{
    int r_no;
    Name name;
    char course[10];
    DOB dob;
    float fees;
};
int main()
{
   struct studentinfo stud;
   printf("\nEnter registration number : ");
   scanf("%d",&stud.r_no);
   printf("Enter First name :\n");
   scanf("%s",stud.name.frstnme);
   printf("Enter Middle name :\n");
   scanf("%s",stud.name.mdlenme);
   printf("Enter Last name :\n");
   scanf("%s",stud.name.lstnme);
   printf("\n");
   printf("Enter DOB [dd.mm.yy]:");
   scanf("%d %d %d",&stud.dob.dd,&stud.dob.mm,&stud.dob.yy);
   printf("\nEnter the fees:");
   scanf("%f",&stud.fees);

   printf("\n ***Student's details***");
   printf("\nRegistration number : %d",stud.r_no);
   printf("\nName of student : %s %s %s",stud.name.frstnme,stud.name.mdlenme,stud.name.lstnme);
   printf("\nD.O.B- %d.%d.%d",stud.dob.dd,stud.dob.mm,stud.dob.yy);
   printf("\nTotal Fees :%f",stud.fees);
} 

Solution

  • Your code should allow the user to skip the input, let's say, by pressing enter, leaving the buffer empty, I mean with \0 only, you could use fgets for this, but a problem remains, if the input is larger than what the buffer can take, the remaing contents on stdin will be left there, compromising future readings.

    I'd suggest using a more personalized method:

    // Required headers:

    #include <stdlib.h>
    #include <assert.h>
    

    // Helper functions:

    int clearbuffer() { // helper function to clear buffer
        int c;
        while ((c = getchar()) != '\n' && c != EOF){} 
        if (c == EOF) {
            return EXIT_FAILURE;
        }
        return EXIT_SUCCESS;
    }
    
    int readline(char *buffer, size_t size) { // custom line reading function
        assert(size > 0 && size <= INT_MAX);  // validate size parameter
        size_t i = 0;
        int ch;
        // reads at most size of the buffer - 1, clearing the extra characters
        while ((ch = fgetc(stdin)) != '\n' && ch != EOF) {
            if(i < size - 1){
                buffer[i++] = ch;
            }
        }    
        buffer[i] = '\0';
        return i;
    }
    

    // Main code:

    int main(){
        struct studentinfo stud;
        size_t namesize = 0; //keep track of the student name length
    
        printf("\nEnter registration number : ");
        scanf("%d", &stud.r_no);
    
        printf("Enter First name(Enter to skip): ");
        if(clearbuffer() == EXIT_FAILURE){
            fprintf(stderr, "Fatal error");
            return EXIT_FAILURE;
        }
        namesize += readline(stud.name.frstnme, sizeof stud.name.frstnme);
    
        printf("Enter Middle name(Enter to skip): ");
        namesize += readline(stud.name.mdlenme, sizeof stud.name.mdlenme);
    
        printf("Enter Last name name(Enter to skip): ");
        namesize = readline(stud.name.lstnme, sizeof stud.name.lstnme);
    
        printf("Enter DOB [dd.mm.yy]: ");
        scanf("%d %d %d", &stud.dob.dd, &stud.dob.mm, &stud.dob.yy);
    
        printf("\nEnter the fees: ");
        scanf("%f", &stud.fees);
    
        printf("\n ***Student's details***");
        printf("\nRegistration number : %d", stud.r_no);
        if(namesize > 0) // if all three names are empty, no need to print this
            printf("\nName of student : %s %s %s", stud.name.frstnme, stud.name.mdlenme, stud.name.lstnme);
        printf("\nD.O.B- %d.%d.%d", stud.dob.dd, stud.dob.mm, stud.dob.yy);
        printf("\nTotal Fees :%f", stud.fees);
    }
    

    There are still some issues you could fix in your code to make it more robust, namely input values validation, which is hard to do with scanf, I'd suggest reading the input as text (with fgets or the custom line reader function provided above) and safely converting the values with strtol / strtod.

    Alternatively you should document the behavior of the code in case of invalid inputs, be it values outside the range allowed or invalid inputs.

    I'd also suggest the more precise double type, instead of float.

    Minor issue, you are using typedef in your structure struct studentinfo with no effect, you forgot to give it a name.