使用C中的fread从标准输入读取缓冲 [英] Buffered reading from stdin using fread in C
问题描述
我试图有效地从标准输入
使用 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, ÷nd);
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屋!