【问题标题】:Why does my fgets method turn out to be like this?为什么我的 fgets 方法会变成这样?
【发布时间】:2016-02-15 00:36:26
【问题描述】:

我无法输入我的“详细信息”,因为它没有给我留下任何空间。

   int addTask(NODE **head){
//IGNORE NODES
        NODE *p, *temp, *ptr, *a;
        DATE d;
        p = *head;
        a = *head;
        char x[32];
        char y[32];
        char name[32];
        char details[128];
        int month;
        int day;
        int year;
        int priority;
        int intDate;
        int i;
        printf("\n");
        printf("Enter task name: ");
        scanf("%s", name);
        printf("Enter task details:");
        fgets(details, 128, stdin); //PROBLEM LIES HERE
        printf("[mm dd yyyy] Enter task deadline: ");
        scanf("%d %d %d", &month, &day, &year);
        printf("Enter priority: ");
        scanf("%d", &priority);

        /*code conditions here*/
    }

在我的终端中,结果是这样的:

User@Lynn /cygdrive/c/users/user/academic/c
$ gcc -o a  Yago_exer11.c

User@Lynn /cygdrive/c/users/user/academic/c
$ ./a

1. Add a task
2. Remove a task
3. Search for a task
4. View all tasks
5. View tasks by priority
6. Exit
Choice: 1

Enter task name: hello
Enter task details:[mm dd yyyy] Enter task deadline: 09 09 09 //PROBLEM
Enter priority: 1
Adding...

我尝试使用 scanf(%^[\n]) 作为替代方案,但结果却是相同的输出。谁能告诉我我的代码有什么问题?

【问题讨论】:

  • 呃,哦!不要混合使用scanffgets,因为它们处理换行符的方式不同。最好采取两步法:首先使用fgets 读取行,然后使用sscanf 扫描这些行或将它们标记化。
  • 哦,我明白了!再次感谢你! :D

标签: c string input fgets


【解决方案1】:

尝试将 getchar(); 放在 scanf("%s", name);

之后

【讨论】:

    【解决方案2】:

    fgetsscanf 函数的工作方式不同。最好不要混用。

    scanf 扫描输入。它不知道线条;它将所有换行符、制表符和空格简单地视为“空白”。它也在转换后停止,因此在读取后,下一个文件读取操作直接在该输入之后开始,通常就在新行之前。 (当输入卡在不是数字的地方时,尝试一遍又一遍地解析十进制数字也是一个陷阱。)

    fgets 从输入中读取行。该方法更适合您的提示输入策略:程序提出问题,用户回答并按 Enter。

    我建议采用两步法。首先读取行,然后分析这些行并提取数据。根据数据的样子,您可以使用strtok 标记行并转换标记,或者您可以使用sscanfscanf 的姊妹函数扫描字符串来扫描数据。

    这是您示例的一个版本,显示了使用该两步方法解析输入的几种策略:

    #include <stdlib.h>
    #include <stdio.h>
    #include <string.h>
    
    int main(void)
    {
        char line[128];
        char name[32];
        char details[128];
        int month;
        int day;
        int year;
        int priority;
        int n;
    
        // read lines until one of them contains a word
        printf("Enter task name: ");
    
        do {
            if (fgets(line, sizeof(line), stdin) == 0) return 1;
            n = sscanf(line, "%s", name);
        } while (n != 1);
    
        // details may be empty, so read them directly
        printf("Enter task details: ");
    
        if (fgets(details, sizeof(details), stdin) == 0) return 1;
        strtok(details, "\n");
    
        // prompt and read lines until one of them has a valid date
        do {
            printf("[mm dd yyyy] Enter task deadline: ");
    
            if (fgets(line, sizeof(line), stdin) == 0) return 1;
            n = sscanf(line, "%d %d %d", &month, &day, &year);
            if (n == 3) {
                if (month < 1 || month > 12) n = 0;
                if (day < 1 || day > 31) n = 0;
            }
            if (n != 3) printf("Invalid date\n");
        } while (n != 3);
    
        // read priority until a number (any number) is given
        printf("Enter priority: ");
        do {
            if (fgets(line, sizeof(line), stdin) == 0) return 1;
            n = sscanf(line, "%d", &priority);
        } while (n != 1);
    
        // echo results
        printf("name: %s\n", name);
        printf("details: %s\n", details);
        printf("data: %02d/%02d/%04d\n", month, day, year);
        printf("prio: %d\n", priority);
    
        return 0;
    }
    

    这个例子远非完美。例如,当用户按下 Ctrl-Z 或 Ctrl-D 结束输入流时会发生什么?标准输入并不特别适合手动输入。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-04-10
      • 2016-06-05
      • 1970-01-01
      • 1970-01-01
      • 2021-11-03
      • 2018-10-15
      相关资源
      最近更新 更多