在遇到一定数量的换行符后,我的程序 return 会是我想要的正确位置吗?
Will my program return the correct position I wanted after meeting a set number of newlines?
我正在尝试向后读取文件(比如文件末尾的 10 行)。每当它读取一个 '\n' 时,我都会增加我的新行计数器 (newline_counter
)。一旦 newline_counter
到达 user_num
(参数),比如 10 行,lseek()
将停止在当前位置(current_pos
)。我正在返回这个位置,这样我就可以在另一个使用 lseek()
的函数中使用这个位置到这个位置,并从这个位置开始读取并写入直到文件末尾。我已经成功编译了程序,但是一旦我开始 运行 它,程序就保持 运行ning 并且没有输出。
int func_line_mode(int infile, int user_num) {
char c;
int newline_counter = 0;
int current_pos = 0;
int end = lseek(infile, 0, SEEK_END);
int counter = 0;
while (counter < end || newline_counter <= user_num) {
lseek(infile, current_pos, SEEK_END);
read(infile, &c, sizeof(char));
if (strcmp(&c,"\n") == 0) {
newline_counter++;
}
current_pos--;
counter++;
}
return current_pos;
}
您的代码存在一些问题:
while
条件错误,应该是:
while (counter < end && newline_counter <= user_num)
在while
之后,你在最后一个换行符之前还有一个字节,所以你应该前进2个字节才能准确:
if (current_pos < 0)
current_pos += 2;
lseek()
return 是 off_t
,而不是 int
,所以你应该这样做:
off_t end = lseek(infile, 0, SEEK_END);
因此,您用于比较的其他变量也应该是 off_t
,最重要的是函数的 return 类型。
strcmp(&c,"\n")
是错误的,要比较单个字符你可以 c == '\n'
.
第 1 条可能是您遇到问题的原因。其他点也应该固定,特别是数字 4.
一旦以上所有问题都解决了,这个功能对我来说就可以正常工作了。这是一个工作示例:
#include <sys/types.h>
#include <unistd.h>
#include <fcntl.h>
#include <stdio.h>
off_t func_line_mode(int infile, int user_num) {
char c;
int newline_counter = 0;
off_t current_pos = 0;
off_t end = lseek(infile, 0, SEEK_END);
off_t counter = 0;
while (counter < end && newline_counter < user_num) {
lseek(infile, current_pos, SEEK_END);
read(infile, &c, 1);
if (c == '\n')
newline_counter++;
current_pos--;
counter++;
}
if (current_pos < 0)
current_pos += 2;
return current_pos;
}
int main() {
char buf[100];
int nread, nwrite;
int fd = open("test.txt", O_RDONLY);
// Last 3 lines.
off_t off = func_line_mode(fd, 3);
printf("off = %d\n", off);
// Go back.
lseek(fd, off, SEEK_END);
while (nread = read(fd, buf, 100)) {
nwrite = 0;
while (nwrite < nread)
nwrite += write(1, buf + nwrite, nread - nwrite);
}
return 0;
}
我正在尝试向后读取文件(比如文件末尾的 10 行)。每当它读取一个 '\n' 时,我都会增加我的新行计数器 (newline_counter
)。一旦 newline_counter
到达 user_num
(参数),比如 10 行,lseek()
将停止在当前位置(current_pos
)。我正在返回这个位置,这样我就可以在另一个使用 lseek()
的函数中使用这个位置到这个位置,并从这个位置开始读取并写入直到文件末尾。我已经成功编译了程序,但是一旦我开始 运行 它,程序就保持 运行ning 并且没有输出。
int func_line_mode(int infile, int user_num) {
char c;
int newline_counter = 0;
int current_pos = 0;
int end = lseek(infile, 0, SEEK_END);
int counter = 0;
while (counter < end || newline_counter <= user_num) {
lseek(infile, current_pos, SEEK_END);
read(infile, &c, sizeof(char));
if (strcmp(&c,"\n") == 0) {
newline_counter++;
}
current_pos--;
counter++;
}
return current_pos;
}
您的代码存在一些问题:
while
条件错误,应该是:while (counter < end && newline_counter <= user_num)
在
while
之后,你在最后一个换行符之前还有一个字节,所以你应该前进2个字节才能准确:if (current_pos < 0) current_pos += 2;
lseek()
return 是off_t
,而不是int
,所以你应该这样做:off_t end = lseek(infile, 0, SEEK_END);
因此,您用于比较的其他变量也应该是
off_t
,最重要的是函数的 return 类型。strcmp(&c,"\n")
是错误的,要比较单个字符你可以c == '\n'
.
第 1 条可能是您遇到问题的原因。其他点也应该固定,特别是数字 4.
一旦以上所有问题都解决了,这个功能对我来说就可以正常工作了。这是一个工作示例:
#include <sys/types.h>
#include <unistd.h>
#include <fcntl.h>
#include <stdio.h>
off_t func_line_mode(int infile, int user_num) {
char c;
int newline_counter = 0;
off_t current_pos = 0;
off_t end = lseek(infile, 0, SEEK_END);
off_t counter = 0;
while (counter < end && newline_counter < user_num) {
lseek(infile, current_pos, SEEK_END);
read(infile, &c, 1);
if (c == '\n')
newline_counter++;
current_pos--;
counter++;
}
if (current_pos < 0)
current_pos += 2;
return current_pos;
}
int main() {
char buf[100];
int nread, nwrite;
int fd = open("test.txt", O_RDONLY);
// Last 3 lines.
off_t off = func_line_mode(fd, 3);
printf("off = %d\n", off);
// Go back.
lseek(fd, off, SEEK_END);
while (nread = read(fd, buf, 100)) {
nwrite = 0;
while (nwrite < nread)
nwrite += write(1, buf + nwrite, nread - nwrite);
}
return 0;
}