输入从过去输入流中读取字符的行中的字符和整数

时间:2014-09-07 12:02:20

标签: c input scanf

我总是擅长在C中输入字符,这是另一个例子。虽然我理解(也许)发生了什么,但我无法找到解决方案。

我有以下代码

scanf("%ld %ld",&n,&m);

for(i=0;i<n;i++)
    scanf("%ld",&array[i]);

for(i=0;i<m;i++)
{
    fflush(stdin);
    //inputting a character 'R' but it is picking '\n' from past buffer
    scanf("%c",&query);

    //As a result of above problem, it is also acting wierd for same reason
    scanf("%ld",&d);

    printf("%c %ld",query,d);
    printf("\nI=%ld\n",i);
}

请帮我弄清楚它发生的原因以及解决方案。

2 个答案:

答案 0 :(得分:1)

scanf%d(或%ld)一起使用只会从输入流中提取数字;它会在流中留下换行符。

因此,当您编写scanf("%c"时,它会读取该换行符。

要解决此问题(如果您的意图是scanf("%c"读取下一行的第一个字符),则需要刷新上一行的输入。一种方法是:

int ch; while ( (ch == getchar()) != EOF && ch != '\n' ) { }

您的行fflush(stdin);会导致未定义的行为 - 请勿这样做。 fflush函数仅用于输出流。

此外,检查scanf的返回值是一个非常好的主意。如果不是您的预期,那么您可能希望采取一些行动,而不是假装输入了一个数字。

答案 1 :(得分:1)

由于您厌倦了输入问题,我可以为您提供一种有助于简化生活的方法 我可以观察到:

  • 您在处理行尾时遇到问题。
  • 有时您需要输入数字,有时您需要字符或其他类型的输入。所以,你(想你)被迫使用格式化输入。

我的建议是,您将阅读输入的问题与解释从输入输入的数据的问题分开。

标准C在标准标题<stdio.h>中仅带来一些处理输入/输出操作的函数 如果您对非常柔和的I / O结果不感兴趣,那么标准库就足够了 但是,<stdio.h>的功能通常会产生输入当时读取一行的效果,其中包括行尾字符:{{ 1}}。

你可以做什么,接下来是:

  1. 使用'\n'读取一行并将结果放入缓冲区(不要太长),仅用于此目的。
     一旦您阅读了整行,就不会再出现行尾的问题。
  2. 然后,重新读取该行,将其保存在缓冲区中,并将所需的所有格式化输入应用于该行。
  3. 一个简短的例子:

    fgets(..., stdin)

    因此,每当您需要将输入的一部分与前一部分分开时,只需使用 #include <stdio.h> int main(void) { char buffer[200] = ""; // Initialize array to 0's long int n, m; char c; fgets(buffer, sizeof(buffer), stdin); sscanf(buffer,"%ld %ld",&n,&m); // Now you have processed the "integer number" input, // read input characters again, withou any "flushes" and extrange things: fgets(buffer, sizeof(buffer), stdin); sscanf(buffer,"%c", &c); fgets(buffer, sizeof(buffer), stdin); // and so on... } 执行新行读取,该行将输入存储在fgets(..., stdin)中,然后处理{{ 1}} buffer,将格式字符串应用于buffer而不是输入本身(以其肉体为单位)。

    注意:此方法可能会遇到一些问题:如果字符串输入的字符数超过sscanf()(在示例中为200),则不会完全读取该行。可以通过检查buffer 中的最后一个字符是否等于sizeof(buffer)还是buffer来处理这种情况。在这种情况下,你会自动进行某种&#34;刷新输入&#34;操作(读取和丢弃字符,直到找到下一个行尾)。