使用fscanf获取输入

时间:2016-05-15 16:02:13

标签: c

我正在构建一个程序,使用户能够输入电影并打印出用户输入的信息。

我正在使用struct来定义电影的变量。问题是,当用户输入第一个带有空格的fscanf() 时。示例:“Miami Vice”所有其他puts()相互打印。 stdin之后无效。我不知道为什么会这样。

我一直在阅读关于gets()并且它有安全问题所以我应该使用fgets()或fscanf()来实现这一点。但我无法弄清楚这里的问题是什么。

的main.c

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

int main()
{
    struct movie m;

    puts("What was the title of the movie you saw?");
    fscanf(stdin, "%s", m.title);
    puts("What was the relase year?");
    fscanf(stdin, "%d", &m.year);
    puts("How would you rate the movie? (1-10)");
    fscanf(stdin, "%d", &m.rate);

    printf("You saw the movie %s which was released %d and you rated it a %d", m.title, m.year, m.rate);

    return 0;
}

main.h

struct movie {
    char title[40];
    int rate;
    int year;
};

2 个答案:

答案 0 :(得分:1)

每当读取字符串作为输入时,请尝试使用fgets()。无论如何这里是我修改了一下的代码。您可以根据自己的需要修改代码。

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

struct movie {
    char title[40];
    int rate;
    int year;
};

int main(){

   struct movie m;
   char *newline_char=NULL;

   puts("What was the title of the movie you saw?");
   fgets(m.title,40,stdin);

   //The below two lines of code are used to remove the '\n'
   //character from the input since fgets() also stores the '\n'
   //character. Replace the '\n' char with '\0' character.
   if((newline_char=strchr(m.title,'\n')) != NULL){
    *newline_char = '\0';
   }

   puts("What was the relase year?");
   fscanf(stdin, "%d", &m.year);
   puts("How would you rate the movie? (1-10)");
   fscanf(stdin, "%d", &m.rate);

   printf("You saw the movie %s which was released %d and you rated it a %d", m.title, m.year, m.rate);
   return 0;
}

正如chux建议的那样,您也可以只使用fgets()并避免fscanf(),如下面的代码所示,

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

struct movie {
    char title[40];
    int rate;
    int year;
};

int main(){

    struct movie m;
    char *newline_char=NULL;
    char input[256];

    puts("What was the title of the movie you saw?");
    fgets(m.title,40,stdin);

    if((newline_char=strchr(m.title,'\n')) != NULL){
       *newline_char = '\0';
    }

    puts("What was the relase year?");
    fgets(input,256,stdin);
    sscanf(input,"%d",&m.year);
    puts("How would you rate the movie? (1-10)");
    fgets(input,256,stdin);
    sscanf(input,"%d",&m.rate);

    printf("You saw the movie %s which was released %d and you rated it a %d", m.title, m.year, m.rate);
    return 0;
}

答案 1 :(得分:0)

%s格式指示scanf读取单个字词。空格充当单词分隔符,因此只有Miami被解析为m.title并且Vice保留在输入流中。对scanf格式%d的后续调用无法解析流中的整数并返回0,导致m.yearm.date未初始化。因此,在最后一次调用printf时打印其值时,会调用未定义的行为。

您可以使用其他格式更正问题:%[^\n]。此外,您应该使用宽度说明符scanf阻止m.title%39[^\n]的末尾写入。如果在电影标题之前存在空格,则格式之前的其他将跳过空格。另外%*c会读取\n,但不是必需的,因为后续的scanf("%d",...)会跳过前导空格,包括输入流中待处理的\n待处理空白。

以下是您的计划的修改版本:

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

struct movie {
    char title[40];
    int rate;
    int year;
};

int main(void) {
    struct movie m;

    puts("What was the title of the movie you saw?");
    if (scanf(" %39[^\n]", m.title) != 1)
        return 1;
    puts("What was the release year?");
    if (scanf("%d", &m.year) != 1)
        return 1;
    puts("How would you rate the movie? (1-10)");
    if (scanf("%d", &m.rate) != 1)
        return 1;

    printf("You saw the movie %s which was released in %d and you rated it a %d\n",
           m.title, m.year, m.rate);

    return 0;
}