如何在C中读取一个整数后跟一个字符串?

时间:2016-04-07 07:03:14

标签: c

我正在尝试编写一个简单的程序,它将读取两个输入行,一个整数,后跟一个字符串。但是,它似乎对我不起作用。

int main()
{
    int i;
    char str[1024];

    scanf("%d", &i);
    scanf("%[^\n]", str);
    printf("%d\n", i);
    printf("%s\n", str);

    return 0;
}

输入整数并按“Enter”后,程序立即打印整数。它不等我输入字符串。怎么了?什么是正确的编程方式?

3 个答案:

答案 0 :(得分:3)

您需要知道的事情

%[^\n]的问题在于,当要读取的第一个字符是换行符时,会失败,并将其推回stdin

问题

输入第一个scanf的号码后,按 Enter 。第一个%d中的scanf使用该数字,将 Enter keypress生成的换行符('\n')留在标准输入流中({{ 1}})。下一个stdin中的%[^\n]会看到此scanf,但由于此答案第一段中给出的原因而失败。

修复

解决方案包括:

  • \n更改为scanf("%d", &i);scanf("%d%*c", &i);的作用是,它扫描并丢弃一个角色。

    我不推荐这种方式,因为邪恶的用户可以通过输入%*c,例如:scanf来欺骗<number><a character>\n,并且您将再次遇到同样的问题。< / p>

  • 2j\n之前添加空格(任何空格字符都可以),即将%[^\n]更改为scanf("%[^\n]", str); @Bathsheba mentioned in a comment。< / p>

    空格字符的作用是,它扫描并丢弃任意数量的空白字符,包括无字符,直到第一个非空白字符。

    这意味着在输入第二个scanf(" %[^\n]", str);时,将跳过任何前导空白字符。

  • 这是我的建议:在scanf之后清除stdin。创建一个函数:

    scanf

    并使用void flushstdin(void) { int c; while((c = getchar()) != '\n' && c != EOF); } 每次scanf后调用它。

其他问题:

与您的问题无关的问题包括:

  • 如果flushstdin();失败,则不处理此案例。这可能是由于各种原因造成的,例如输入格式错误,例如为scanf输入字母表。

    为此,请检查%d的返回值。它返回成功扫描和分配的项目数,如果遇到scanf,则返回-1。

  • 您不检查缓冲区溢出。您需要阻止超过1023个字符(NUL终止符为+1)扫描到EOF

    这可以通过使用str中的长度说明符来实现。

  • 标准要求使用scanfmain声明int main(void),而不是int main(int argc, char* argv[])
  • 您忘记加入int main()stdio.hprintf

已修复,完成程序

scanf

答案 1 :(得分:0)

这很简单,就可以了:

scanf("%d %[^\n]s", &i, str);

答案 2 :(得分:0)

Instateed scanf()使用fgets()后跟sscanf()

使用<stdio.h>中的原型检查几乎所有函数的返回值。

#include <stdio.h>

int main(void) {
    int i;
    char test[1024]; // I try to avoid identifiers starting with "str"

    char tmp[10000]; // input buffer

    // first line
    if (fgets(tmp, sizeof tmp, stdin)) {
        if (sscanf(tmp, "%d", &i) != 1) {
            /* conversion error */;
        }
    } else {
        /* input error */;
    }
    // second line: read directly into test
    if (fgets(test, sizeof test, stdin)) {
        size_t len = strlen(test);
        if (test[len - 1] == '\n') test[--len] = 0; // remove trailing ENTER

        // use i and test
        printf("i is %d\n", i);
        printf("test is \"%s\" (len: %d)\n", test, (int)len);

    } else {
        /* input error */;
    }
    return 0;
}