scanf() 第二次获取字符串

scanf() to get in the string on the second time

scanf()第二次获取字符串有什么问题,我第二次输入不了我的字符串。 我不确定发生的错误,我不能很好地运行这个程序

#include <stdio.h>
#include <stdlib.h>

int main()
{
    //variables decleration
    char staff_name1[31];
    char staff_name2[31];
    float sales1, sales2;

    //input
    printf("Enter staff name\t> ");
    scanf("%[^\n]s", staff_name1);

    printf("Enter sales amount\t> ");
    scanf("%f", &sales1);

    printf("\nEnter staff name \t> ");//ERROR,CAN'T INPUT MY STRING
    fflush(stdin);
    scanf("%[^\n]s", staff_name2);

    printf("\nEnter sales amount\t> ");
    scanf("%f", &sales2);

    printf("\n");

    //output
    printf("Staff Name\t\t\t\tSales Amount\n");
    printf("===================\t\t=============\n");
    printf("%-20s \t%12.2f\n", staff_name1, sales1);
    printf("%-20s \t%12.2f\n", staff_name2, sales2);


}

我的这段代码的输出如下:

warning: this program uses gets(), which is unsafe.

Enter staff name   > kh s
Enter sales amount > 134.14

Enter staff name   > 
Enter sales amount > 141243.14

Staff Name              Sales Amount
===================     =============
kh s                          134.14
                           141243.14

我无法输入第二个员工姓名。谁能帮我解决这个问题??

你遇到了三个问题。

  1. 我看到你使用 %[^\n]s。这是错误的。 s 不是 %[ 说明符的一部分。所以使用 %[^\n] 而不是 %[^\n]s
  2. 输入 sales1 的值后,按 Enter。此字符保留在 stdin(标准输入流)中。而当 %[^\n] 的下一个字符是 \n 时,它将失败。通过在 %[^\n].
  3. 之前添加 space 来解决此问题
  4. stdin 上使用 fflush 会根据 C11 标准调用未定义的行为,尽管该行为在某些实现中已明确定义。最好去掉它,这样你的代码会更便携。

补充说明:

  • 您可以限制要扫描的字符数量,以避免buffer overflows
  • 您可以检查scanf的return值以确保成功。程序中的所有 scanf 都将 return 1 成功。


固定程序:

#include <stdio.h>
#include <stdlib.h> //Unused header

int main()
{
    char staff_name1[31];
    char staff_name2[31];
    float sales1, sales2;


    printf("Enter staff name\t> ");
    if(scanf(" %30[^\n]", staff_name1) != 1)
    {
        printf("Could not scan staff_name1");
        return -1;   //Exit main with a return value of -1
    }

    printf("Enter sales amount\t> ");
    if(scanf("%f", &sales1) != 1)
    {
        printf("Could not scan sales1");
        return -1;   //Exit main with a return value of -1
    }

    printf("\nEnter staff name \t> ");
    //fflush(stdin); UB!
    if(scanf(" %30[^\n]", staff_name2) != 1)
    {
        printf("Could not scan staff_name2");
        return -1;   //Exit main with a return value of -1
    }

    printf("\nEnter sales amount\t> ");
    if(scanf("%f", &sales2) != 1)
    {
        printf("Could not scan sales2");
        return -1;   //Exit main with a return value of -1
    }

    printf("\n");

    //output
    printf("Staff Name\t\t\t\tSales Amount\n");
    printf("===================\t\t=============\n");
    printf("%-20s \t%12.2f\n", staff_name1, sales1);
    printf("%-20s \t%12.2f\n", staff_name2, sales2);


}
fflush(stdin);

在标准 C 中是 未定义的行为。要刷新换行符,您可以简单地使用 getchar()

printf("\nEnter staff name \t> ");
getchar();
scanf("%[^\n]s", staff_name2);

我还会使用 fgets() 而不是 scanf 来读取一行,并在必要时使用 trim 换行符,这样可以更好地控制用户输入的无效输入并防止缓冲区溢出。