0

我正在尝试读取一个包含 1024 行的文件,每行中有 9 个相同的字母,如果找到与此术语不匹配的行,则返回。

该文件如下,但有 1024 行:

eeeeeeeee
eeeeeeeee
eeeeeeeee

代码:

fd = open(fileName, O_RDONLY);
lseek(fd,0,SEEK_SET);


if(flock(fd, LOCK_SH) == -1)
        perror("error on file lock");

if(fd != 0){

    read(fd, lineFromFile, (sizeof(char)*10));
    arguments->charRead = lineFromFile[0];

    for(i=0; i < 1024; i++){        
        var = read(fd, toReadFromFile, (sizeof(char)*10));  
        if(strncmp(toReadFromFile,lineFromFile,10) != 0 || var < 10){           

            arguments->result = -1;
            printf("%s \n\n",toReadFromFile);
            printf("%s \n",lineFromFile);
            printf("i %d var %d  \n",i,var);                
            free(toReadFromFile);
            free(lineFromFile);
            return ;
        }                       
    }
}

输出:

> eeeee
eeee 

eeeee
eeee 
i 954 var 6 

我有 5 个具有不同字母的不同文件,每个文件都在该特定行 (954) 中给出此输出,并且该行是正确的,字母写了 9 次,最后带有 \n。

任何想法为什么会发生这种情况?如果我不使用 lseek 它可以正常工作,但我需要 lseek 将文件分成几个部分以由不同的线程进行测试。我将 0 索引放在 lseek 中,以简化给大家看。

谢谢。

4

2 回答 2

1

看起来您正在寻找"eeeee\neeee"而不是"eeeeeeeee\n". 这意味着您的文件应该像这样开始:

eeeee
eeeeeeeee
eeeeeeeee

并像这样结束:

eeeeeeeee
eeee

如果你的文件这样结束:

eeeeeeeee
eeeeeeeee

然后当你到达最后一行时,它会失败,因为你只会阅读"eeeee\n"而不是"eeeee\neeee".

鉴于您评论中的新信息,我认为问题在于您不应该寻找行的中间(在本例中为 342 和 684)。您应该寻找预期字符串的偶数倍数(如 340 和 680)。此外,第 954 行不是问题发生的地方。它应该是第 954 + X 行,其中 X 是您要查找的行。

于 2014-11-14T18:40:52.753 回答
1

不管你的程序可能有什么其他问题,它肯定有这个:read()函数不能保证读取请求的全部字节数。除非遇到错误或文件结尾,否则它将读取至少一个,并且在许多情况下它确实读取了请求的全部字节数,但即使在文件结尾之前还有足够的字节数,read()也可能读取更少比请求的字节数。

敦促您使用更高级别函数的注释是经过深思熟虑的,但如果您由于某种原因有义务使用,read()那么您必须注意读取的字节数少于请求的字节数的情况,并通过将额外的字节读取到未使用的字节中来处理它们缓冲区的尾端。可能多次。

在函数形式中,它可能如下所示:

int read_all(int fd, char buf[], int num_to_read) {
    int total_read = 0;
    int n_read = 0;

    while (total_read < num_to_read) {
        n_read = read(fd, buf + total_read, num_to_read - total_read);
        if (n_read > 0) {
            total_read += n_read;
        } else {
            break;
        }
    }

    return (n_read < 0) ? n_read : total_read;
}
于 2014-11-14T18:55:36.953 回答