C lseek行为不端
C lseek misbehaving
我正在尝试编写一个程序来模拟 C 中的 tail
行为。在文件中搜索“/n”字符时,我从 lseek 得到了一个奇怪的行为。这是相关的代码:
FILE *myfile = fopen(argv[i], "r");
if (myfile == NULL) {
printf("File not valid. Skipping.\n");
continue;
}
//Go to the end of the file - You have to find the pos of the n lines.
off_t pos = lseek(fileno(myfile), 0, SEEK_END);
if (pos == -1) {
perror("Lseek");
}
int l = 0;
int temp = 10; //ofc there is a lines variable not hardcoded, this is just for testing purposes
pos--;
off_t pos2 = lseek(fileno(myfile), pos, SEEK_SET);
printf("pos2: %ld\n", pos2);
off_t curpos = 0;
while ((l = fgetc(myfile)) != EOF && temp >= 0) {
curpos = lseek(fileno(myfile), 0, SEEK_CUR);
printf("Curpos: %ld; pos: %ld\n", curpos, pos);
if (l == '\n') {
temp--;
}
pos--;
lseek(fileno(myfile), pos, SEEK_SET);
}
运行 这段代码给了我那些 printf 语句:
pos2: 25699
CurPos: 25700; pos: 25699 //EOF
CurPos: 25700; pos: 25698 //EOF
CurPos: 25697; pos: 25697
CurPos: 25700; pos: 25696 //EOF
CurPos: 25695; pos: 25695
CurPos: 25694; pos: 25694
CurPos: 25693; pos: 25693
CurPos: 25700; pos: 25692 //EOF
CurPos: 25691; pos: 25691
CurPos: 25690; pos: 25690
CurPos: 25689; pos: 25689
CurPos: 25688; pos: 25688
CurPos: 25687; pos: 25687
CurPos: 25686; pos: 25686
CurPos: 25685; pos: 25685
and so on but it never goes to EOF again
所以它四次进入 EOF 并再次读取 EOF 之前的最后一个 '\n',给我错误的结果。
将 while body 切换为:
while (pread(fileno(myfile), &l, 1, pos) != 0 && temp >= 0) {
if (l == '\n') {
temp--;
}
pos--;
}
给我预期的行为。
所以,我想知道,为什么我的第一个 while body 坏了?
编辑:固定格式和无关紧要的东西
您不应将对 FILE * 的操作与对基础文件描述符的操作混合使用。如果您在文件描述符上 lseek
,那么随后对 fgetc
的调用将是……错误的。使用 fseek
.
而不是 lseek
我正在尝试编写一个程序来模拟 C 中的 tail
行为。在文件中搜索“/n”字符时,我从 lseek 得到了一个奇怪的行为。这是相关的代码:
FILE *myfile = fopen(argv[i], "r");
if (myfile == NULL) {
printf("File not valid. Skipping.\n");
continue;
}
//Go to the end of the file - You have to find the pos of the n lines.
off_t pos = lseek(fileno(myfile), 0, SEEK_END);
if (pos == -1) {
perror("Lseek");
}
int l = 0;
int temp = 10; //ofc there is a lines variable not hardcoded, this is just for testing purposes
pos--;
off_t pos2 = lseek(fileno(myfile), pos, SEEK_SET);
printf("pos2: %ld\n", pos2);
off_t curpos = 0;
while ((l = fgetc(myfile)) != EOF && temp >= 0) {
curpos = lseek(fileno(myfile), 0, SEEK_CUR);
printf("Curpos: %ld; pos: %ld\n", curpos, pos);
if (l == '\n') {
temp--;
}
pos--;
lseek(fileno(myfile), pos, SEEK_SET);
}
运行 这段代码给了我那些 printf 语句:
pos2: 25699
CurPos: 25700; pos: 25699 //EOF
CurPos: 25700; pos: 25698 //EOF
CurPos: 25697; pos: 25697
CurPos: 25700; pos: 25696 //EOF
CurPos: 25695; pos: 25695
CurPos: 25694; pos: 25694
CurPos: 25693; pos: 25693
CurPos: 25700; pos: 25692 //EOF
CurPos: 25691; pos: 25691
CurPos: 25690; pos: 25690
CurPos: 25689; pos: 25689
CurPos: 25688; pos: 25688
CurPos: 25687; pos: 25687
CurPos: 25686; pos: 25686
CurPos: 25685; pos: 25685
and so on but it never goes to EOF again
所以它四次进入 EOF 并再次读取 EOF 之前的最后一个 '\n',给我错误的结果。
将 while body 切换为:
while (pread(fileno(myfile), &l, 1, pos) != 0 && temp >= 0) {
if (l == '\n') {
temp--;
}
pos--;
}
给我预期的行为。
所以,我想知道,为什么我的第一个 while body 坏了?
编辑:固定格式和无关紧要的东西
您不应将对 FILE * 的操作与对基础文件描述符的操作混合使用。如果您在文件描述符上 lseek
,那么随后对 fgetc
的调用将是……错误的。使用 fseek
.
lseek