encore 的博客

encore 的博客

streambuf读优模板

posted on 2019-03-20 21:10:00 | under 语言相关 |

rt,有bug可以评论或者以任何形式@我

常数还可以再优化,这里主要是提供一个思路。

已知可能是bug的:

  • 控制台下调试可能需要多摁几下ctrl+Z,freopen之类无影响。

希望有大佬可以帮忙解决。

【190327更新】

  • 新增redc,redst分别用于读入字符,字符串。暂不支持std::string。

主要是为了解决字符和数字混搭的题目的要求。


namespace IO{
    using std::cin;
    using std::cout;
    using std::endl;

    namespace IN {
        #define getc() (p1 == p2 && (p2 = (p1 = buf) + inbuf -> sgetn(buf, MAX_INPUT), p1 == p2) ? EOF : *p1++)
        const int MAX_INPUT = 1000000;
        char buf[MAX_INPUT], *p1, *p2;

        template <typename T> 
        inline int 
        redi(T &x) {
            static std::streambuf *inbuf = cin.rdbuf();
            x = 0;
            register int f = 0, flag = 1;
            register char ch = getc();
            if (ch == EOF) return EOF;
            while (!std::isdigit(ch)) {
                if (ch == '-') f = 1;
                ch = getc();
            }
            if (std::isdigit(ch)) x = x * 10 + ch - '0', ch = getc(), flag = 0;
            while (std::isdigit(ch)) {
                x = x * 10 + ch - 48;
                ch = getc();
            }
            x = f ? -x : x ;
            return ch == EOF ? EOF : flag;
        }

        template <typename T,typename ...Args> 
        inline int 
        redi(T& a,Args& ...args) {
            if (redi(a) != EOF) {
                redi(args...);
                return 0;
            } 
            else return EOF;
        }

        inline int 
        redc(char &ch) {
            static std::streambuf *inbuf = cin.rdbuf();
            return (ch = getc()) == EOF ? EOF : 0;
        }

        inline int 
        redst(char *st) {
            if (redc(*st) != EOF && (*st)) while (redc(*(++ st)) != EOF);
            else return EOF; 
            return 0;
        }
        #undef getc
    }

    namespace OUT {

        template <typename T> 
        inline void 
        put(T x) {
            static std::streambuf *outbuf = cout.rdbuf();
            static char stack[21];
            static int top = 0;

            if (x < 0) {
                outbuf -> sputc('-');
                x=-x;
            }
            if (!x) {
                outbuf -> sputc('0');
                outbuf -> sputc('\n');
                return;
            }
            while (x) {
                stack[++top] = x % 10 + '0';
                x /= 10;
            }
            while (top) {
                outbuf -> sputc(stack[top]);
                -- top;
            }
            outbuf -> sputc('\n');
        }

        inline void 
        putc (const char ch) {
            static std::streambuf *outbuf = cout.rdbuf();
            outbuf -> sputc(ch);
        }

        template<typename T>
        inline void 
        put_non(T x)
        {
            static std::streambuf *outbuf = cout.rdbuf();
            static char stack[21];
            static int top = 0;
            if (x < 0) {
                outbuf -> sputc('-');
                x=-x;
            }
            if (!x) {
                outbuf -> sputc('0');
                return;
            }
            while (x) {
                stack[++top] = x % 10 + '0';
                x /= 10;
            }
            while (top) {
                outbuf -> sputc(stack[top]);
                --top;
            }
        }

        template <typename T> 
        inline void 
        put(const char ch,T x)
        {
            static std::streambuf *outbuf = cout.rdbuf();
            static char stack[21];
            static int top = 0;
            if (x < 0) {
                outbuf -> sputc('-');
                x=-x;
            }
            if (!x) {
                outbuf -> sputc('0');
                outbuf -> sputc(ch);
                return;
            }
            while (x) {
                stack[++top] = x % 10 + '0';
                x /= 10;
            }
            while (top) {
                outbuf -> sputc(stack[top]);
                --top;
            }
            outbuf -> sputc(ch);
        }

        inline void 
        putst(const char *st)
        {
            static std::streambuf *outbuf = cout.rdbuf();
            do { outbuf->sputc(*(st ++));} while (*st);
        }

        template <typename T> 
        inline void 
        put(const char *st,T x)
        {
            static std::streambuf *outbuf = cout.rdbuf();
            static char stack[21];
            static int top = 0;
            if (x < 0) {
                outbuf -> sputc('-');
                x=-x;
            }
            if (!x) {
                outbuf -> sputc('0');
                putst(st);
                return;
            }
            while (x) {
                stack[++top] = x % 10 + '0';
                x /= 10;
            }
            while (top) {
                outbuf -> sputc(stack[top]);
                --top;
            }
            putst(st);
        }

        template<typename T,typename ...Args> 
        inline void 
        put(T a,Args ...args) {
            put(a);put(args...);
        }

        template<typename T,typename ...Args> 
        inline void 
        put(const char ch,T a,Args ...args) {
            put(ch,a);put(ch,args...);
        }

        template<typename T,typename ...Args> 
        inline void 
        put(const char *st,T a,Args ...args) {
            put(st, a);put(st,args...);
        }
    }

    using IN::redi;
    using IN::redc;
    using IN::redst;
    using OUT::put_non;
    using OUT::put;
    using OUT::putc; 
    using OUT::putst;
}