一次笔试的时候,有一题,要求使用非脚本语言读取一个文本文件的行数,刚好这几天再看Richard Stevens的《Unix网络编程》,刚好里面有关于readline函数的实现,看代码:
/* * readline.c * * Created on: Feb 23, 2013 * Author: root */#include #include #include #include ssize_tread_line(int fd, void *vptr, ssize_t maxlen){ ssize_t n, rc; char c, *ptr; ptr = vptr; for (n = 1; n < maxlen; n++) { again: if ((rc = read(fd, &c, 1)) == 1) { *ptr++ = c; if (c == '\n') break; } else if (rc == 0) { *ptr = 0; return(n - 1); } else { if (errno == EINTR) goto again return(-1); } } *ptr = 0; return(n);}
这个代码还是比较容易理解的,但是,作者在原文中也说过,这个是极其缓慢的读取方式,因为read函数每次只能读取一个字符,而read函数读取的字节数实际上是由第三个参数来决定的,下面就是改进了的readline函数
/* * readline.c * * Created on: Feb 23, 2013 * Author: root */#include #include #include #include #define MAXLINE 40static int read_cnt;static char *read_ptr;static char read_buf[MAXLINE];static ssize_tmy_read(int fd, char *ptr){ printf("a%d\n", read_cnt); 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; printf("%d\n", read_cnt); } read_cnt--; *ptr = *read_ptr++; return(1);}ssize_tread_line(int fd, void *vptr, ssize_t maxlen){ ssize_t n, rc; char c, *ptr; ptr = vptr; for (n = 1; n < maxlen; 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);}
一次readMAXLINE个字符,将返回的read_cnt个字节保存在readbuf里面,然后,然后利用read_cnt来控制循环,找到里面的'\n'