为什么我的fgets方法结果是这样的?

时间:2015-11-13 12:16:43

标签: c string input fgets

我无法输入我的“细节”,因为它不会为我留下任何空间。

   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])作为替代,但事实证明它具有相同的输出。有人能告诉我我的代码有什么问题吗?

2 个答案:

答案 0 :(得分:0)

尝试在 scanf之后放置 getchar(); ("%s",名称);

答案 1 :(得分:0)

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

scanf扫描输入。它不了解线条;它将所有换行符,制表符和空格简单地视为" white space"。它也会在转换后停止,因此在读取之后,下一个文件读取操作将在该输入之后直接启动,这通常在新行之前。 (当输入卡在不是数字的东西时,还有一次尝试解析十进制数的缺陷。)

fgets从输入中读取行。使用提示和输入策略时,该方法更自然:程序提出问题,用户回答并按回车。

我建议采用两步法。首先读取行,然后分析这些行并提取数据。根据数据的外观,您可以使用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结束输入流时会发生什么?标准输入并不特别适合手动输入。