使用C中的fread从标准输入读取缓冲 [英] Buffered reading from stdin using fread in C

查看:431
本文介绍了使用C中的fread从标准输入读取缓冲的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图有效地从标准输入使用 setvbuf用来在`〜_IOFBF读取模式。我是新来缓冲。我要寻找的工作的例子。

I am trying to efficiently read from the stdin by using setvbuf in `_IOFBF~ mode. I am new to buffering. I am looking for working examples.

输入以两个整数( N K )。接下来的输入的n个行包含1的整数。这样做的目的是打印多少个整数整除由 K

The input begins with two integers (n,k). The next n lines of input contain 1 integer. The aim is to print how many integers are divisible by k.

#define BUFSIZE 32
int main(){
  int n, k, tmp, ans=0, i, j;
  char buf[BUFSIZE+1] = {'0'};
  setvbuf(stdin, (char*)NULL, _IONBF, 0);
  scanf("%d%d\n", &n, &k);
  while(n>0 && fread(buf, (size_t)1, (size_t)BUFSIZE, stdin)){
    i=0; j=0;
    while(n>0 && sscanf(buf+j, "%d%n", &tmp, &i)){
    //printf("tmp %d - scan %d\n",tmp,i); //for debugging
      if(tmp%k==0)  ++ans;
      j += i; //increment the position where sscanf should read from
      --n;
    }
  }
  printf("%d", ans);
  return 0;
}

问题是如果数为界,的缓存 BUF 会读 23 2354 \\ n ,当它应该已经读过 2354 (它不能),或什么都没有。

The problem is if number is at the boundary, the buffer buf will read 23 from 2354\n, when it should have either read 2354 (which it cannot) or nothing at all.

我怎样才能解决这个问题呢?

How can I solve this issue?

编辑结果
<一href=\"http://stackoverflow.com/questions/2371292/buffered-reading-from-stdin-using-fread-in-c/2378520#2378520\">Resolved现在(与分析)。

编辑结果
完成问题说明

推荐答案

版本1:使用 getchar_unlocked 作为R塞缪尔Klatchko(见注释)建议

Version 1 : Using getchar_unlocked as suggested by R Samuel Klatchko (see comments)

#define BUFSIZE 32*1024
int main(){
  int lines, number=0, dividend, ans=0;
  char c;
  setvbuf(stdin, (char*)NULL, _IOFBF, 0);// full buffering mode
  scanf("%d%d\n", &lines, ÷nd);
  while(lines>0){
    c = getchar_unlocked();
    //parse the number using characters
    //each number is on a separate line
    if(c=='\n'){
      if(number % dividend == 0)    ans += 1;
      lines -= 1;
      number = 0;
    }
    else
      number = c - '0' + 10*number;
  }

  printf("%d are divisible by %d \n", ans, dividend);
  return 0;
}


版本2:使用 FREAD 来读取它的块和解析数

#define BUFSIZE 32*1024
int main(){
int lines, number=0, dividend, ans=0, i, chars_read;
char buf[BUFSIZE+1] = {0}; //initialise all elements to 0
scanf("%d%d\n",&lines, &dividend);

while((chars_read = fread(buf, 1, BUFSIZE, stdin)) > 0){
  //read the chars from buf
  for(i=0; i < chars_read; i++){
    //parse the number using characters
    //each number is on a separate line
    if(buf[i] != '\n')
      number = buf[i] - '0' + 10*number;
    else{
      if(number%dividend==0)    ans += 1;
      lines -= 1;
      number = 0;
    }       
  }

if(lines==0)  break;
}

printf("%d are divisible by %d \n", ans, dividend);
return 0;
}


结果:(10万个号码由11整除测试)


Results: (10 million numbers tested for divisibility by 11)

运行1:(不setvbuf用来第1版)0.782秒结果
  运行2:(与setvbuf用来版本1)0.684秒结果
  运行3:(第2版)0.534

Run 1: ( Version 1 without setvbuf ) 0.782 secs
Run 2: ( Version 1 with setvbuf ) 0.684 secs
Run 3: ( Version 2 ) 0.534

P.S。 - 每次运行使用-O1标志GCC编译

P.S. - Every run compiled with GCC using -O1 flag

这篇关于使用C中的fread从标准输入读取缓冲的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆