===========骨灰级菜鸟的第一篇技术博客,勿喷=========
同学写了一个快速读入int和string的程序,用较底层的fread读入数据,我理解了一下,现贴上源码以及自己添加的注释,表示对大神的崇敬
同学写了一个快速读入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均为表达式(函数调用或者语句)*/
/*逗号表达式的值就是最后一个表达式的值*/
/* }}}*/