Pro_4_UNIX下高效readline函数的实现_2016_08_10

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里面取读出相应的数据。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值