对身边的大神写的快速读入int和string方法的解读

===========骨灰级菜鸟的第一篇技术博客,勿喷=========
同学写了一个快速读入int和string的程序,用较底层的fread读入数据,我理解了一下,现贴上源码以及自己添加的注释,表示对大神的崇敬

===========骨灰级菜鸟的第一篇技术博客,勿喷=========



/*
 * $File: fast-read.cc
 * $Date: Fri Dec 21 14:44:05 2012 +0800
 * $Author: Xinyu Zhou <zxytim[at]gmail[dot]com>
 *
 * A template for fast read of integer and string.
 *
 * This implementation is in MACRO format because it
 * yields a slightly faster code that that of using
 * function calls.
 *
 * This version of code uses a fixed size buffer to store
 * inputs by *fread*, and analyze the string manually to convert it
 * to int or string. Also, update the buffer when it is exhausted.
 *
 * sample usage:
 *    READ_INT(num);
 *    READ_STR(str); // str is a char*, which no boundary checking
 */


/* {{{ fast read*/
#include <cstdio>
#include <cctype>


FILE *fast_read_fin = stdin;


const int N_BUF_MAX = 10000;
char fast_read_buffer[N_BUF_MAX];
char *fast_read_ptr = fast_read_buffer + N_BUF_MAX,
     *fast_read_buf_end = fast_read_buffer + N_BUF_MAX;


/*都是宏定义,包含了很多宏定义的技巧*/
#define PTR_NEXT() \
    do { \
        if (fast_read_ptr != fast_read_buf_end) \
            break; \
        fast_read_ptr = fast_read_buffer; /*效果:当指针指到末尾时重新指到流的开头*/\
        fread(fast_read_buffer, N_BUF_MAX, 1, fast_read_fin); /*读入*/\
    } while (0) /*只读入一次,使用这个循环体,是为了可以中途break;*/
/*关于宏定义的技巧,最后没有打分号,为了和调用时的语法 PTR_NEXT(); 后面的分号兼容,*/


#define READ_INT(__num__)  \
    do { \
        int ret = 0, sign = 1; \
        for (; ;) /*将fast_read_ptr指向第一个数字或负号*/\
        { \
            PTR_NEXT(); \
            if (isdigit(*fast_read_ptr) || (*fast_read_ptr) == '-') \
                break; \
            fast_read_ptr ++; \
        } \
        if ((*fast_read_ptr) == '-') /*若fast_read_ptr指向负号,标记并指向下一个数字*/\
        { \
            sign = -1; \
            fast_read_ptr ++; \
        } \
        for (; ;) /*计算输入的数字*/\
        { \
            PTR_NEXT(); \
            if (!isdigit(*fast_read_ptr)) \
                break; \
            ret = ret * 10 + (*(fast_read_ptr ++)) - '0'; \
        } \
        (__num__) = ret * sign; \
    } while (0)


#define READ_STR(__str__) \
    ({ \
        char *start = (__str__), \
             *ret = start; \
        do { \
            for (; ;) /*将fast_read_ptr指向第一个非空白字符*/\
            { \
                PTR_NEXT(); \
                if (!isspace(*fast_read_ptr)) \
                    break; \
                fast_read_ptr ++; \
            } \
            for (; ;) /*将输入的非空白字符存起来*/\
            { \
                PTR_NEXT(); \
                if (isspace(*fast_read_ptr)) \
                    break; \
                *(ret ++) = *(fast_read_ptr ++); /*将输入的非空白字符存起来*/\
            } \
            (*ret) = 0; \
        } while (0); \
        ret - start;  /*这是逗号表达式的最后一个表达式,其值就是ret - start*/\
    }) /*逗号表达式  (a1, a2, a3);  a1,a2,a3均为表达式(函数调用或者语句)*/ 
       /*逗号表达式的值就是最后一个表达式的值*/
/* }}}*/


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值