一次笔试的时候,有一题,要求使用非脚本语言读取一个文本文件的行数,刚好这几天再看Richard Stevens的《Unix网络编程》,刚好里面有关于readline函数的实现,看代码:
/*
* readline.c
*
* Created on: Feb 23, 2013
* Author: root
*/
#include
#include
#include
#include
ssize_t
read_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 40
static int read_cnt;
static char *read_ptr;
static char read_buf[MAXLINE];
static ssize_t
my_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_t
read_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'