1

It's a simple C program. I've declared a structure named EmployeeDetails Now I'm trying to take four different inputs for every Employee and at last print them according to the input provided. But the program is not working as expected. Like sometimes the scanf() works sometime it gets skipped which results in some garbage value at the time of printing in the end. Check the output at the end for more clarity.

#include <stdio.h>
#define MAX_SIZE 40
int main() {
    struct EmployeeDetails
    {
        char name[MAX_SIZE];
        int dlnumber;
        char route[MAX_SIZE];
        float kmsdrove;
    } e1, e2 ;

    printf("1st Employee. Enter Your Name :\n");
    scanf("%[^\n]%*c", e1.name);
    printf("Kindly Provide us Your Driving License(DL) No. :\n");
    scanf("%d", &e1.dlnumber);
    printf("Route on Which You're Going to Drive :\n");
    scanf("%[^\n]%*c", e1.route);
    printf("How many Kms You already drove? :\n");
    scanf("%f", &e1.kmsdrove);

    printf("2nd Employee. Enter Your Name :\n");
    scanf("%[^\n]%*c", e2.name);
    printf("Kindly Provide us Your Driving License(DL) No. :\n");
    scanf("%d", &e2.dlnumber);
    printf("Route on Which You're Going to Drive :\n");
    scanf("%[^\n]%*c", e2.route);
    printf("How many Kms You already drove? :\n");
    scanf("%f", &e2.kmsdrove);

    printf("1st Employee Details: \n");
    printf("Name: %s\n", e1.name);
    printf("DL No.: %d\n", e1.dlnumber);
    printf("Route: %s\n", e1.route);
    printf("Kms already covered: %0.02f\n", e1.kmsdrove);

    printf("2nd Employee Details: \n");
    printf("Name: %s\n", e2.name);
    printf("DL No.: %d\n", e2.dlnumber);
    printf("Route: %s\n", e2.route);
    printf("Kms already covered: %0.02f\n", e2.kmsdrove);


    return 0;
}

Output of the program:

1st Employee. Enter Your Name :
Ravi
Kindly Provide us Your Driving License(DL) No. :
454
Route on Which You're Going to Drive :
How many Kms You already drove? :
4
2nd Employee. Enter Your Name :
Kindly Provide us Your Driving License(DL) No. :
32
Route on Which You're Going to Drive :
How many Kms You already drove? :
54
1st Employee Details: 
Name: Ravi
DL No.: 454
Route: 
Kms already covered: 4.00
2nd Employee Details: 
Name:   
DL No.: 32
Route: �U
Kms already covered: 54.00

Kindly help.

Reet Priye
  • 13
  • 3
  • 2
    `scanf("%d"` leaves the newline in the input. – KamilCuk Jul 08 '20 at 10:55
  • 1
    If you have any problem with using scanf then use its return value to describe in detail. I.e. report the values you get here in contrast to those you expect, that will help you focus the question. – Yunnosch Jul 08 '20 at 10:56
  • You cannot use ANY input function correctly unless you ***check the return***. – David C. Rankin Jul 10 '20 at 00:01
  • And general discussion about `scanf()` use and validation, see [How do I limit the input of scanf to integers and floats(numbers in general)](https://stackoverflow.com/questions/53726736/how-do-i-limit-the-input-of-scanf-to-integers-and-floatsnumbers-in-general/53727344?r=SearchResults&s=3|45.4652#53727344) – David C. Rankin Jul 10 '20 at 00:53

2 Answers2

0

The problem is you need to clear the last char("\n") read by the scanf not only in strings, but also in %d and %f. It's just better to use %*c on all scanfs like scanf("%d%*c",x);

0

the following proposed code snippet:

  1. shows how to check for an error from scanf()
  2. documents the reason each header file is included
  3. demonstrates the proper/safe way to write a %[...] input format conversion specifier
  4. demonstrates how to handle a error from scanf()
  5. makes use of appropriate horizontal and vertical spacing for readability

And now, the proposed code snippet:

#include <stdio.h>    // scanf(), fprintf(), printf()
#include <stdlib.h>   // exit(), EXIT_FAILURE


#define MAX_SIZE 40

// note the proper signature for 'main'
int main( void ) 
{
    // for flexibility, 
    // separate struct definition 
    // from 
    // instances of the struct
    struct EmployeeDetails
    {
        char name[ MAX_SIZE ];
        int dlnumber;
        char route[ MAX_SIZE ];
        float kmsdrove;
    };
    
    // following instances would be better written as:
    // struct EmployeeDetails employees[2]
    // then a loop could be used to enter the employees
    // rather than the extended list of repeated code.
    struct EmployeeDetails e1;
    struct EmployeeDetails e2;
    
    // note the leading space in the format string
    // that leading space consumes all leading 'white space'
    printf( "1st Employee. Enter Your Name :\n" );
    if( scanf( " %39[^\n]", e1.name) != 1 )
    {
        fprintf( stderr, "scanf for first emp name failed\n" );
        exit( EXIT_FAILURE );
    }
    
    printf( "Kindly Provide us Your Driving License(DL) No. :\n" );
    if( scanf( "%d", &e1.dlnumber ) != 1 )
    {
        fprintf( stderr, "scanf for first emp drive license failed\n" );
        exit( EXIT_FAILURE );
    }
    
    // note the MAX CHARACTERS modifier on the '%[...]' 
    // that is 1 less than the length of the input buffer
    // because `%s` and `%[...]` always append a NUL to the input
    // This avoids any possibility of a buffer overflow and the
    // resulting undefined behavior
    printf( "Route on Which You're Going to Drive :\n" );
    if( scanf( " %39[^\n]", e1.route ) != 1 )
    {
        fprintf( stderr, "scanf for emp 1 route failed\n" );
        exit( EXIT_FAILURE );
    }

 
user3629249
  • 16,402
  • 1
  • 16
  • 17