C-函数读取(文件、缓冲区、要读取的字节)中断字符串

C-函数读取(文件、缓冲区、要读取的字节)中断字符串,c,pthreads,lseek,C,Pthreads,Lseek,我试图读取一个1024行的文件,每行包含9倍的相同字母,如果它发现一行与这个术语不匹配,就会返回 文件如下,但有1024行: eeeeeeeee eeeeeeeee eeeeeeeee > eeeee eeee eeeee eeee i 954 var 6 代码: fd = open(fileName, O_RDONLY); lseek(fd,0,SEEK_SET); if(flock(fd, LOCK_SH) == -1) perror("error on

我试图读取一个1024行的文件,每行包含9倍的相同字母,如果它发现一行与这个术语不匹配,就会返回

文件如下,但有1024行:

eeeeeeeee
eeeeeeeee
eeeeeeeee
> eeeee
eeee 

eeeee
eeee 
i 954 var 6 
代码:

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 ;
        }                       
    }
}
我有5个具有不同字母的不同文件,每个文件都在该特定行(954)中给出此输出,该行正确,字母写了9次,最后有一个\n

你知道为什么会这样吗?如果我不使用lseek,它可以正常工作,但是我需要lseek将文件分成几个部分,由不同的线程进行测试。我将0索引放在lseek中,以便于简化,从而向大家展示


谢谢。

看起来您要找的是
“eeeee\neeee”
而不是
“eeeeeee\n”
。这意味着您的文件应该如下所示开始:

eeeee
eeeeeeeee
eeeeeeeee
eeeeeeeee
eeee
eeeeeeeee
eeeeeeeee
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;
}
最后是这样的:

eeeee
eeeeeeeee
eeeeeeeee
eeeeeeeee
eeee
eeeeeeeee
eeeeeeeee
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;
}
如果文件的结尾如下所示:

eeeee
eeeeeeeee
eeeeeeeee
eeeeeeeee
eeee
eeeeeeeee
eeeeeeeee
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;
}
然后当您到达最后一行时,它将失败,因为您将只读取
“eeeee\n”
,而不是
“eeeee\neeee”


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

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

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

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

eeeee
eeeeeeeee
eeeeeeeee
eeeeeeeee
eeee
eeeeeeeee
eeeeeeeee
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;
}
int read_all(int fd,char buf[],int num_to_read){
int total_read=0;
int n_read=0;
while(总读取数<总读取数){
n_read=读取(fd,buf+总读取,num_to_read-总读取);
如果(n_读取>0){
总读取次数+=n次读取;
}否则{
打破
}
}
返回值(n\u读取<0)?n\u读取:总读取;
}

如果您试图逐行读取文本文件,最好让库函数通过使用
fgets()
fscanf()
为您完成这项工作。每个线程不必使用
fseek()。另一种方法是将整个10k文件(不是很大,你知道它的大小)读入所有线程可用的静态内存中,让它们都检查同一个副本。可能是因为你从文件中读取时,你的另一个线程正在对你的文件执行
lseek
?您应该将
lseek
向下移动到锁定文件的位置下方。这样一来,一旦你有了锁,你就只能
lseek
。问题是,因为我已经有其他程序使用读取整个文件的线程,这个新程序需要共享同一个文件才能更快地测试它,我的老师说必须使用lseek()和read()。我不明白它怎么能适用于大多数生产线,却在特定的生产线失败。没有意义。您是否在所有线程中共享相同的
fd
?或者你是在每个线程调用
open
一次吗?我将lseek移动到锁后,它也会这样做。我在每个线程上使用一个
open
,但在第954行失败,最后一行是1024。如果我对以下lseek使用3个线程:lseek(fd,0,SEEk_SET)lseek(fd,342,SEEk_SET)lseek(fd,684,SEEk_SET)-前两个线程成功,最后一个线程在第954行失败。如果它是从EEEE开始的,那么前两个线程不应该失败吗?还是只在第1024行失败?很有趣。你为什么要找342和684?你不应该寻求可以被10整除的偏移量吗?另外,您不应该查看文件中的第954行。你应该看X+954行,其中X是你要找的线。在您的例子中,您搜索到了第68行的中间,因此问题发生在第68+954=1022行,或者如果第一行是第1行,则出现在第1023行。您是对的:我更改了for并保存了lseek的返回,如下所示:
newIndex=lseek(fd,arguments->startineIndex*10,SEEK\u SET)
for(i=newIndex/10;ifinishLineIndex;i++)
Thanksalready solved,但还是要谢谢你。我真的需要使用lseek来完成这一步。您可能确实需要使用
lseek()
,但这并不意味着您也不需要执行我描述的操作。即使到目前为止,你的程序碰巧给了你预期的结果,但总是依赖它来实现这一点是不安全的。