给出应用程序read-data
的以下代码,该代码只需将stdin
中的数据读取到分配给堆的缓冲区buf
中:
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
const size_t BUF_SIZE=1048576*256; // Just for testing, don't do this in prod code
const size_t MAX_READ_SIZE=1048576;
int main(int argc, char *argv[])
{
// Allocate buffer space on the heap
char *buf=(char *) malloc(BUF_SIZE);
// Check for malloc failure
if (buf==NULL)
{
fprintf(stderr,"Unable to allocate %zu bytes\n");
return 1;
}
size_t curOffset=0;
// Read MAX_READ_SIZE (or smaller) blocks until EOF
// WARNING: Don't do this in actual "live" code, since it can result
// in a buffer overflow with an input whose size
// exceeds that of the pre-allocated buffer
while (ssize_t numRead=read(STDIN_FILENO,buf+curOffset,MAX_READ_SIZE)>0)
{
fprintf(stderr,"Bytes read: %zu\n",numRead);
curOffset+=numRead;
}
// Free buffer space
free(buf);
fprintf(stderr,"Total bytes read: %zu\n",curOffset);
}
测试:
$ cat | ./read-data
a
Bytes read: 1
b
Bytes read: 1
c
Bytes read: 1
d
Bytes read: 1
Total bytes read: 4
所有换行符和它们的“字节”在哪里?每个输入应该读取两个字节,总共应该读取8个字节。
比较例如:
使用基本的Unix工具进行测试:
$ cat | printf 'Total bytes read: %u\n' "$(wc --bytes)"
a
b
c
d
Total bytes read: 8
更奇怪的是,给定文件four-lines.txt
时,我什至有更疯狂的行为:
$ cat four-lines.txt
a
b
c
d
$ wc --bytes four-lines.txt
8 four-lines.txt
$ <four-lines.txt ./read-data
Bytes read: 1
Total bytes read: 1
该错误必须很明显,但是我只能说: WTF?
更新:正如安德鲁指出的那样,该错误是错误地假设该行中的运算符优先级的问题:
while (ssize_t numRead=read(STDIN_FILENO,buf+curOffset,MAX_READ_SIZE)>0)
是否可以更改行,以便可以将定义放在while
条件内?还是必须在while
之前定义numRead?
更新2:修复很明显,感谢WhozCraig
的回答,使变量定义的范围限于循环的主体:
for (ssize_t numRead=0;
(numRead=read(STDIN_FILENO,buf+curOffset,MAX_READ_SIZE))>0;
)
...
答案 0 :(得分:4)
您没有将任务缩小到足够的范围:
while (ssize_t numRead=read(STDIN_FILENO,buf+curOffset,MAX_READ_SIZE)>0)
将比较结果 分配给numRead
,即0或1。
您要分配的是read
的结果:
ssize_t numRead;
while ((numRead=read(STDIN_FILENO,buf+curOffset,MAX_READ_SIZE)) > 0)