Pro_4_UNIX下高效readline函数的实现_2016_08_10
2016-08-11 07:35
519 查看
readline.c
#include <stdio.h> #include <unistd.h> #include <fcntl.h> #include <errno.h> #include <stdlib.h> #include <string.h> /* * 抄自《UNIX网络编程:卷1》, 稍作修改。 * 仅仅用于学习目的。学无止境,进步每一天。 * * slickedit编辑。 * * 254008829@qq.com * */ #define MAXLINE 1024 static int read_cnt; static char *read_ptr; static char read_buf[MAXLINE]; static ssize_t my_read(int fd, char *ptr) { if (read_cnt <= 0) { again: if ( (read_cnt = read(fd, read_buf, sizeof(read_buf))) < 0) { if (errno == EINTR) goto again; return -1; } else if (read_cnt == 0) { return 0; } read_ptr = read_buf; } read_cnt--; *ptr = *read_ptr++; return 1; } ssize_t my_readline(int fd, void *vptr, size_t maxline) { ssize_t n, rc; char c, *ptr; ptr = vptr; for (n=1; n<maxline; n++) { if ( (rc = my_read(fd, &c)) == 1) { *ptr++ = c; if (c == '\n') break; } else if (rc == 0) { *ptr = 0; return n -1; } else return -1; } *ptr = 0; return n; } ssize_t readbufline(char **vptr) { if (read_cnt > 0) *vptr = read_ptr; return read_cnt; } // 这个宏是为了调用其中的func,类似包裹函数。只有当所调用的函数(func), 以返回小于0的数字为错误值的时候才适用。 #define FUNC_RET(func, val) \ do { \ int rv; \ if ( (rv=func) < 0) { \ printf("LINE = %d, error str: %s\n", __LINE__, strerror(errno)); \ perror("FUNC_RET"); \ exit(-1); \ } \ val = rv; \ } while (0); /* 自己实现的main函数 */ int main(int argc, char **argv) { if (argc != 2) { printf("Usage: %s filename\n", argv[0]); exit(0); } int filefd, ret; char readbuf[MAXLINE] = {0}; FUNC_RET(open(argv[1], O_RDONLY), filefd); FUNC_RET(my_readline(filefd, readbuf, sizeof(readbuf)), ret); printf("I get a line @\"%s\": %s\n", argv[1], readbuf); FUNC_RET(close(filefd), ret); exit(0); } /* 编译readline.c生成raadline可执行文件,然后执行命令:./readline readline.c 结果为: I get a line @"readline.c": #include <stdio.h> */
> 上述my_read, my_readline函数用到了文件自带的缓冲read_buf。my_read函数一次系统调用read将读到数据放到read_buf中,my_readline函数从read_buf里面取读出相应的数据。
相关文章推荐
- Pro_6_UNIX下TCP回射服务与客户程序优化版_2016_08_17
- Pro_5_UNIX下TCP回射服务与客户程序_2016_08_15
- APUE读书笔记-02UNIX标准和实现-08系统基本类型
- Pro_1_UNIX下最简单的C_S程序_2016_8_5
- 再读C++ Primer 写了个小例子——实现Vector类的自动添加元素功能(08-12-10)
- Java_Pro3_枚举类深入2_08_10
- OpenCV3.0 Examples学习笔记(10)-grabcut.cpp-grabcut函数实现人机交互高效分割图像前景背景
- 2016/10/08 上班第一天
- unix 利用fork 和sleep 实现的排序,主要是练习 apue chapter 10 fork 和 execlp
- 再读C++ Primer 写了个小例子——实现stack类的压栈弹栈功能(08-12-10)
- 2016 08 10 css选择器练习——常用属性
- Java利用protostuff实现高效序列化
- UNIX环境下如何应用消息队列实现进程间通信
- 花1K内存实现高效I/O的RandomAccessFile类
- ASP.NET中利用DataGrid的自定义分页功能和存储过程结合实现高效分页
- 使用水晶报表JRC(Java Report Component)在Unix下实现实时报表
- UNIX下实现终端打印的几种方法
- 利用DataGrid的自定义分页功能和存储过程结合实现高效分页
- VB.NET 实现DirectSound9 (10) 均衡器
- 3D游戏引擎设计与实现(10)