C语言getline函数复现版本的工作原理是什么?_getline与_getchar如何协同运行?
_getchar 函数功能
这个是单字符读取的底层实现:
- 直接调用系统调用
read从标准输入每次读取1个字节 - 读取返回值为0代表已经读到输入流末尾,返回
EOF标记 - 读取返回值为-1代表出现IO错误,直接终止程序返回状态码99
- 读取成功就返回读到的字符(转int类型兼容
EOF标记的返回)
注:这个复现版本的
_getchar固定读取标准输入,所以上层_getline传入的stream参数实际上没有被使用,属于简化实现的缺陷。
_getline 函数功能
这个是整行读取的上层实现,三个参数分别为:存放结果的缓冲区二级指针lineptr、记录缓冲区大小的变量指针n、输入流指针stream。运行逻辑如下:
- 先做参数合法性校验,三个指针只要有一个为NULL,直接返回-1表示调用失败
- 如果用户没有预先分配缓冲区(即
*lineptr为NULL),会自动申请120字节的内存作为初始缓冲区,申请失败返回-1,同时将*n赋值为120记录当前缓冲区大小 - 进入循环调用
_getchar逐个读取字符:- 每次读取字符前先判断已读字符数是否超过缓冲区大小,如果超出就触发扩容,每次额外新增120字节,扩容失败返回-1,同时更新缓冲区地址和大小记录
- 将读到的字符写入缓冲区对应的位置
- 如果读到换行符
\n,直接终止循环
- 如果循环终止是因为读到
EOF,返回-1 - 最后在缓冲区末尾补上字符串结束符
\0,返回实际读到的字符总长度(包含换行符)
二者协同工作流程
两个函数是典型的底层单字符读取、上层组装成行的分层实现逻辑,举个实际读取的例子:
假设用户在终端输入this is a test line\n:
- 调用
_getline时如果没有传入预分配的缓冲区,_getline先申请120字节的初始缓冲区 _getline循环调用_getchar,依次拿到t、h、i、s……直到读到最后的\n- 本次输入总长度不到120字节,不需要触发扩容,所有字符直接写入缓冲区
- 读到
\n后终止循环,在缓冲区末尾补\0,返回读取到的字符总长度 - 如果输入的内容长度超过120字节,
_getline会自动触发realloc扩容,每次新增120字节,直到能装下整行内容为止。
内容的提问来源于stack exchange,提问作者NoahVerner
相关产品推荐
相关产品推荐

