【问题标题】:C/C++ printf() and scanf() reversed when running the program运行程序时 C/C++ printf() 和 scanf() 反转
【发布时间】:2017-08-06 05:39:16
【问题描述】:

这是我的代码:

#include <stdio.h>
#include <stdlib.h>
enum abcd{aaaa,bbbb,cccc,dddd,z};

typedef struct stct{
    abcd eAbcd;
    int x;
} stct;
typedef struct indexx{
    int size;
    struct stct *addr;
} indexx;

void add_item(indexx *idx);
stct read_in();

int main()
{
    indexx idx = {0, NULL};
    int op;
    while (1)
    {
        printf("\n1. add item\n4. quit\n");
        scanf("%d\n", &op);
        switch (op)
        {
            case 1:
                add_item(&idx);
                break;
            case 4:
                return 0;
            default:
                printf("Please enter a correct number\n");
        }
    }
}

void add_item(indexx *idx)
{
    stct *newdata;
    newdata = (stct *) realloc(idx->addr, idx->size*sizeof(stct));
    if (newdata)
    {
        idx->size ++;
        idx->addr = newdata;
        idx->addr[idx->size-1] = read_in();
    }
    else
        printf("No memory\n");
}

stct read_in()
{
    stct temp;
    int ab;
    temp.eAbcd = z;
    while (temp.eAbcd != aaaa && temp.eAbcd != bbbb && temp.eAbcd != cccc && temp.eAbcd != dddd)
    {
        printf("select(1-4):\n");
        scanf("%d", &ab);
        ab-=1;
        switch (ab)
        {
            case 0: temp.eAbcd = aaaa; break;
            case 1: temp.eAbcd = bbbb; break;
            case 2: temp.eAbcd = cccc; break;
            case 3: temp.eAbcd = dddd; break;
        }
    }
    scanf("%d", &temp.x);
    return temp;
}

它应该在scanf()之前打印出select(1-4):,但是当我编译并运行程序时,我得到了这个:

1
select(1-4):

(1是我输入的。)

我已经尝试了C/C++ printf() before scanf() issue 中的解决方案,但它们都不适合我。

【问题讨论】:

  • 所以你添加了例如fflush() 就像那里的建议?
  • 你在哪里运行这个?
  • @Sridharan 在 fedora 26 上运行,使用 g++ 7.1.1 编译
  • @FelixPalmen 是的,我已经尝试了该问题答案中的所有解决方案
  • 好吧,无法复制(我很确定没有其他人可以)。也许您没有显示全部您的代码。通过添加 #include &lt;stdio.h&gt;main 函数将其转换为 minimal reproducible example 可以按预期工作。

标签: c printf scanf


【解决方案1】:

您的问题在 行:

    scanf("%d\n", &op);

这里的\n 只是一个空白字符(如\t),scanf() 对待任何空白字符都是一样的:它们匹配一个序列 em> 输入流中任意长度(包括 0)的空格。

如果你输入一个数字并回车,你确实输入了一个换行符,而这个换行符确实匹配了\n,它也匹配了\t。但是您不想要匹配它:stdin 默认情况下是行缓冲,并且scanf() 可以选择匹配更多的空白字符,它会等待更多输入以查看是否有更多空白跟随,并且仅在您再次按 Enter 后返回,因为使用 行缓冲,输入仅在换行处可用。

简而言之:这个scanf() 在你再次按回车之前不会完成,所以在你输入之前add_item() 甚至不会被调用。

这里的简单解决方案:从格式字符串中删除伪造的\n

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-04-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多