关于get_next_line函数中file_descriptor作为数组下标的逻辑疑问
问题描述
我知道文件描述符(file descriptor)的概念,但看到get_next_line函数里用文件描述符作为静态数组left_str的下标(比如文件描述符是106时用left_str[106]),搞不懂这么用的逻辑。这个函数是用来从不同文件逐行读取内容并返回的,运行正常,设计目标是打开3个文本文件,循环依次读每个文件的一行(文件1一行、文件2一行、文件3一行,循环执行)。现在需要明确这个下标用法的逻辑。
相关代码
get_next_line函数代码
char *get_next_line(int file_descriptor) { char *line; static char *left_str[4096]; if (file_descriptor < 0 || BUFFER_SIZE <= 0) return (0); left_str[file_descriptor] = ft_read_to_left_str(file_descriptor, left_str[file_descriptor]); if (!left_str[file_descriptor]) return (NULL); line = ft_get_line(left_str[file_descriptor]); left_str[file_descriptor] = ft_new_left_str(left_str[file_descriptor]); return (line); }
main测试函数代码
int main(void) { char *line; int i; int filed1; int filed2; int filed3; filed1 = open("tests/test.txt", O_RDONLY); filed2 = open("tests/test2.txt", O_RDONLY); filed3 = open("tests/test3.txt", O_RDONLY); i = 1; while (i < 7) { line = get_next_line(filed1); printf("line [%02d]: %s", i, line); free(line); line = get_next_line(filed2); printf("line [%02d]: %s", i, line); free(line); line = get_next_line(filed3); printf("line [%02d]: %s", i, line); free(line); i++; } close(filed1); close(filed2); close(filed3); return (0); }
逻辑解析
1. 静态数组的核心作用
static char *left_str[4096]; 是一个静态指针数组,静态变量的特性是程序运行期间内存不会被释放,会保留上次调用后的取值。这刚好匹配get_next_line的需求:每次读取文件时,由于BUFFER_SIZE的存在,可能会一次性读取超过一行的内容,剩下的部分需要暂存起来,供下次调用该文件的get_next_line时继续处理。
2. 用文件描述符当下标的原因
每个打开的文件都对应一个唯一的文件描述符(比如测试代码中filed1、filed2、filed3是三个不同的整数)。用它作为数组下标,相当于给每个打开的文件分配了一块独立的“专属缓冲区”,用来存储该文件上次读取后剩余的未处理内容。
- 比如循环调用
get_next_line(filed1)、get_next_line(filed2)、get_next_line(filed3)时,每次调用只会操作对应文件描述符的left_str元素,完全不会干扰其他文件的暂存内容,保证多个文件的读取状态相互独立。
3. 数组大小设为4096的依据
在类Unix系统中,单个进程默认允许打开的文件描述符上限通常是1024或4096,设置数组大小为4096可以覆盖绝大多数场景,确保所有合法的文件描述符都能找到对应的数组位置。
实际运行场景示例
假设三个文件的描述符分别是3、4、5:
- 第一次调用
get_next_line(3):读取文件1的内容,将超出一行的部分存入left_str[3],返回第一行; - 调用
get_next_line(4):操作left_str[4],处理文件2的内容,和left_str[3]的内容完全无关; - 调用
get_next_line(5):操作left_str[5],处理文件3的内容; - 下一轮循环调用
get_next_line(3):先从left_str[3]取出上次剩余的内容,继续处理,保证文件1的读取是连续的,不会被其他文件的操作打断。
这种设计让get_next_line可以同时处理多个文件的逐行读取,每个文件的读取状态被独立保存,完美满足“循环读取多个文件每行内容”的需求。
内容的提问来源于stack exchange,提问作者galhog

