read()系统调用读取额外的0

时间:2014-11-02 22:44:48

标签: c system-calls

我编写了一个函数,该函数使用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的原因是什么?

1 个答案:

答案 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;
}