我编写了一个函数,该函数使用read()系统调用从文件中读取数字并将它们放入数组中。但是,我注意到最后总是包含额外的0。
int numberRead = 0;
int fp;
char buf[512];
size_t nbytes = sizeof(buf);
int n;
int counter = 0;
char* ptr;
size_t curSize = 16;
int radix = hexFlag ? 16 : 10;
*array = malloc(curSize * sizeof(*array));
fp = open(fname, O_RDONLY);
if (fp == -1) {
return -1;
}
while ((n = read(fp, buf, nbytes)) != 0) {
ptr = strtok(buf, " \n");
while(ptr) {
if (counter >= curSize) {
curSize += 16;
*array = realloc(*array, curSize * sizeof(**array));
}
(*array)[counter++] = strtol(ptr, NULL, radix);
++numberRead;
ptr = strtok(NULL , " \n");
}
}
归因于strtok
的原因是什么?
答案 0 :(得分:4)
read
没有NULL - 终止它读入的缓冲区,所以这段代码可能会在最后一次读取结束后得到一个额外的数字,这个数字在前一次读取的缓冲区中徘徊。添加以下行:
buf[n] = 0;
紧接在调用read的第一个while
行之后
此外,read
读取的块不一定对应于行或其他任何内容。如果您正在从文件中读取数据,则读取调用可能会返回以多位数字结尾的字符块,在这种情况下,您的代码会将其拆分为两个数字。为了避免这种情况,你不需要尝试对读取的最后几个字符进行标记/解码(在最后一个空格读取之后的所有内容),而是将它们添加到下一个读取中。
您最终需要的代码类似于:
char buf[1024], *end;
size_t n;
size_t leftover = 0;
while ((n = read(fp, buf+leftover, sizeof(buf)-leftover-1)) > 0 || leftover > 0) {
buf[leftover+n] = 0;
ptr = strtok(buf, " \n");
while(ptr) {
if (counter >= curSize) {
curSize += 16;
*array = realloc(*array, curSize * sizeof(**array));
}
(*array)[counter] = strtol(ptr, &end, radix);
if (end == buf+leftover+n && n > 0) {
leftover = ptr-end;
memmove(buf, ptr, leftover);
break; }
++counter;
++numberRead;
ptr = strtok(NULL , " \n");
}
if (!ptr) leftover = 0;
}