fread завершается перед принятием всех пользовательских вводов (из stdin)

#c #buffer #fread

#c #буфер #fread

Вопрос:

Вот решение проблемы CODECHEF «INTEST», которое в основном проверяет, насколько быстро выполняется операция ввода-вывода с помощью кода.

Ввод

Ввод начинается с двух положительных целых чисел nk (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 %lun", amp;n, amp;k);
    input = 0;

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

Они сказали, что fread() предлагает более быстрый ввод-вывод, чем scanf, поскольку fread() выполняет буферный ввод-вывод. Но когда я компилирую и запускаю его на своем собственном компьютере (CODEBLOCKS) и даю ему несколько входных данных с консоли [Примечание: я не передаю входной файл], предположим, что я ввожу 4 3 в первую строку, обозначающую, что за ней следуют еще 4 строки. Но fread() даже не потрудился принять еще 4 строки, и после ввода еще одного ввода в основном программа выводит a 0 , если я ввожу число, кратное 3, или 1 если введенное число не делится на 3 и просто завершается.

  1. Почему fread() завершается перед принятием всех входных данных?
  2. В случае ввода-вывода файлов мы можем быть уверены, что fread() будет читать до тех пор, пока буфер не будет заполнен или не будет обнаружен файловый терминатор. Но в случае stdin, как долго fread() будет ждать, пока пользователь введет входные данные?
  3. Почему программа использует буфер РАЗМЕРОМ 65536?

Комментарии:

1.Имейте в виду, что первое char чтение by fread() выполняется char сразу после ввода for count , которым может быть a 'n' .

Ответ №1:

Когда ввод поступает с терминала, драйвер терминала передает данные после каждой строки и fread() возвращает только то, что доступно. После scanf() первого вызова fread() , скорее всего, вернется только один байт, новая строка, оставленная позади scanf() . После этого каждый вызов будет считывать одну строку, потому что так работает драйвер терминала.

Напротив, если ввод представляет собой обычный файл, то fread() вызов вернет столько символов, сколько доступно, вплоть до размера буфера, полностью игнорируя новые строки как особые случаи.

Если входные данные представляют собой канал, то он будет считывать то, что доступно в канале в любой момент времени, что может быть или не быть несколькими строками данных, в зависимости от того, как они записаны и соответствует ли код чтения коду записи.

Ответ №2:

 #include<stdio.h>
    int main(){
        int i,n,k,m[50],count;
        printf(" ");
        scanf("%d %d",amp;n,amp;k);
        count=0;

        for(i = 1; i <= n; i  ){
           printf(" n");
           scanf("%d",amp;m[i]);
          
               if(m[i] % k==0){
                count=count   1;
             }
           
        }
        printf("ans=%d",count);

        return 0;
    }`enter code here`