gpt4 book ai didi

c - 在 C 中使用 fread 从 stdin 缓冲读取

转载 作者:太空狗 更新时间:2023-10-29 16:56:37 24 4
gpt4 key购买 nike

我试图通过在 `_IOFBF~ 模式下使用 setvbuf 有效地读取 stdin。我是缓冲的新手。我正在寻找有效示例。

输入以两个整数(n,k)开头。接下来的 n 输入行包含 1 个整数。目的是打印有多少整数可以被 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 将从 2354\n 读取 23 >,当它应该读取 2354(它不能读取)或什么都没有时。

我该如何解决这个问题?


编辑
Resolved now (with analysis) .

编辑
Complete Problem Specification

最佳答案

我建议尝试使用 setvbuf 进行完全缓冲并放弃 fread。如果规范是每行一个数字,我就理所当然的,用fgets读取一整行传给strtoul解析数字应该在那条线上。

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

#define INITIAL_BUFFER_SIZE 2 /* for testing */

int main(void) {
int n;
int divisor;
int answer = 0;
int current_buffer_size = INITIAL_BUFFER_SIZE;
char *line = malloc(current_buffer_size);

if ( line == NULL ) {
return EXIT_FAILURE;
}

setvbuf(stdin, (char*)NULL, _IOFBF, 0);

scanf("%d%d\n", &n, &divisor);

while ( n > 0 ) {
unsigned long dividend;
char *endp;
int offset = 0;
while ( fgets(line + offset, current_buffer_size, stdin) ) {
if ( line[strlen(line) - 1] == '\n' ) {
break;
}
else {
int new_buffer_size = 2 * current_buffer_size;
char *tmp = realloc(line, new_buffer_size);
if ( tmp ) {
line = tmp;
offset = current_buffer_size - 1;
current_buffer_size = new_buffer_size;
}
else {
break;
}
}
}
errno = 0;
dividend = strtoul(line, &endp, 10);
if ( !( (endp == line) || errno ) ) {
if ( dividend % divisor == 0 ) {
answer += 1;
}
}
n -= 1;
}

printf("%d\n", answer);
return 0;
}

我使用 Perl 脚本生成 0 到 1,000,000 之间的 1,000,000 个随机整数,并在使用 gcc version 3.4.5 (mingw-vista special r3) 编译此程序后检查它们是否可以被 5 整除我的 Windows XP 笔记本电脑。整个过程不到 0.8 秒。

当我使用 setvbuf(stdin, (char*)NULL, _IONBF, 0); 关闭缓冲时,时间增加了大约 15 秒。

关于c - 在 C 中使用 fread 从 stdin 缓冲读取,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2371292/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com