fread在接受所有用户输入之前终止(来自stdin)

时间:2014-06-22 12:13:51

标签: c buffer fread

这是CODECHEF问题" INTEST"的解决方案,它基本上测试了代码完成IO操作的速度。

输入

输入以两个正整数n k(n,k <= 107)开始。接下来的n行输入包含一个正整数ti,每个不大于109。

输出

写一个整数到输出,表示有多少整数ti可被k整除。

以下代码段是迄今为止提交的最快的C代码:

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

#define SIZE 65535

int main(int argc, char *argv[])
{

    char buffer[SIZE];
    unsigned long n, k, input, count;
    int c, i;
    count = 0;

    scanf("%lu %lu\n", &n, &k);
    input = 0;

    while ((c = fread (buffer, sizeof (char), SIZE, stdin)) > 0)
    {
        for (i = 0; i < c; i++)
        {
            if (buffer[i] == '\n')
            {
                //printf("%d\n", input);
                if ((input % k) == 0)
                {
                    count++;
                }
                input = 0;
            }
            else
            {
                input = (input * 10) + (buffer[i] - '0');
            }
        }
    }
    printf("%lu\n", count);
    return 0;
}

他们说fread()提供比scanf更快的IO,因为fread()执行缓冲IO。但是当我在自己的计算机上编译并运行它(CODEBLOCKS)并从控制台给它一些输入时[注意:我没有输入文件],假设我在第一行输入4 3表示4更多行跟随。但是fread()甚至没有费心去接受另外4行,并且在再接受一次输入之后,如果我输入一个可被3整除的数字,或者如果输入的数字不是0,则程序输出1可被3整除,只是终止。

  1. 为什么fread()会在接受所有输入之前终止?
  2. 如果是文件IO,我们可以确定fread()将一直读取,直到缓冲区已满或遇到文件终止符。但是在stdin的情况下,fread()等待用户输入输入多长时间?
  3. 为什么程序使用SIZE 65536的缓冲区?

1 个答案:

答案 0 :(得分:0)

当输入来自终端时,终端驱动程序在每行之后传递数据,而fread()仅返回可用的数据。在scanf()之后,对fread()的第一次调用可能只会返回一个字节,新行会被scanf()遗留下来。此后,每个调用将读取一行,因为这是终端驱动程序的工作方式。

相反,如果输入是常规文件,那么fread()调用将返回尽可能多的字符,直到缓冲区的大小,完全忽略换行符作为特殊情况。

如果输入是管道,那么它将在任何给定时间读取管道中可用的内容,这可能是也可能不是多行数据,具体取决于它的编写方式以及读取代码是否跟上写作代码。

相关问题