【问题标题】:Why won't it call fgets? [duplicate]为什么它不调用 fgets? [复制]
【发布时间】:2018-06-13 02:18:05
【问题描述】:

代码的目的是查看字符串是如何存储的(是否以\n\0 结尾)。

void print(char*);

int main(void) {

    //fscanf block
    char *ss;
    ss = malloc(sizeof(char)*100);
    printf("String for fscanf: ");
    fscanf(stdin, "%s", ss);
    printf("For fscanf:\n");
    print(ss);

    //fgets block
    char *gs;
    gs = malloc(sizeof(char)*100);
    printf("String for fgets: ");
    fgets(gs, 10, stdin);
    printf("For fgets:\n");
    print(gs);

    free(ss);
    free(gs); 
}

void print(char* str) {
    int done = 0;
    for (int i=0; i<100; i++){
        if (done == 3) {
            break;
        }
        if (str[i] == '\0') {
            printf("Zero: %d\n", i);
            done++;
        }
        if (str[i] == '\n') {
            printf("Return: %d\n", i);
            done++;
        }
    }
}

但是由于某种原因,当我将 fscanf 块放在第一位时,它不会停止并 req 为 fgets 字符串,它只是跳过并输出:

String for fscanf: Hello
For fscanf:
Zero: 5
Zero: 6
String for fgets: For fgets:
Return: 0
Zero: 1

但是当我把 fgets 块放在第一位时,它工作正常:

String for fgets: Hello
For fgets:
Return: 5
Zero: 6
String for fscanf: Hello 
For fscanf:
Zero: 5
Zero: 6

为什么会这样?

【问题讨论】:

标签: c string scanf fgets


【解决方案1】:

scanffscanf 有很多警告 they get their own page in the C FAQ。你mixing fscanf and fgets is covered by 12.18a的特殊问题。

简而言之,您输入了Hello\nfscanf(stdin, "%s", ss) 正在读取字符串 Hello,但不是换行符。那还在stdin上。 fgets 然后读取换行符并停止。在调试这些东西时,最好在调试输出周围加上引号,这样你就可以看到这些东西。 printf("'%s'", gs);

一般情况下,不要混用 fscanffgets。坚持一个或另一个。一般避免scanffscanf 读取和解析行,将读取和解析混为一谈会导致很多问题。相反,使用fgets 读取整行并使用sscanf 解析它。

【讨论】:

    【解决方案2】:

    它没有按预期工作,因为当您执行fscanf(stdin, "%s", ss); 并按下ENTER 时,它会将ENTER 留在第二个缓冲区中。请注意,ENTER 是一个有效字符。因此它将读取\n 以获取第二个输入,并且不会等待fgets(gs, 10, stdin);。为此,您需要在此之后清除 stdin 缓冲区

    fscanf(stdin, "%s", ss);
    

    完成它的一种方法是使用getchar()。例如

    //fscanf block
    
      getchar();/* help to clear the stdin buffer */
    
    //fgets block
    

    另请阅读此处为什么不应该使用 scanf() 以及应该使用什么来代替 scanf() http://c-faq.com/stdio/scanfprobs.html

    【讨论】:

      猜你喜欢
      • 2013-11-21
      • 2011-10-09
      • 2019-11-22
      • 1970-01-01
      • 1970-01-01
      • 2012-07-30
      • 1970-01-01
      • 2013-04-25
      相关资源
      最近更新 更多