无法在 C 中正确使用 scanf() 将字符串作为结构的输入

Unable to take strings as input for structures properly using scanf() in C

这是一个简单的 C 程序。 我已经声明了一个名为 EmployeeDetails 的结构 现在我正在尝试为每个员工获取四个不同的输入,最后根据提供的输入打印它们。 但是该程序没有按预期运行。 就像有时 scanf() 工作有时它会被跳过,这会在最后打印时导致一些垃圾值。 检查最后的输出更清晰。

#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;
}

程序输出:

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

请帮忙。

问题是您需要清除 scanf 读取的最后一个字符 ("\n"),不仅在字符串中,而且在 %d%f 中。最好在所有 scanfs 上使用 %*c,例如 scanf("%d%*c",x);

以下建议的代码片段:

  1. 显示如何检查来自 scanf()
  2. 的错误
  3. 记录包含每个头文件的原因
  4. 演示 proper/safe 编写 %[...] 输入格式转换说明符的方法
  5. 演示如何处理来自 scanf()
  6. 的错误
  7. 利用适当的水平和垂直间距提高可读性

现在,建议的代码片段:

#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 );
    }