也就是输入输出外挂

明明在C语言中有scanf()、printf(),C++中有cin、cout,为什么我们还要用输入输出外挂呢?

这个问题很明显,一定是因为这些输入输出函数功能过于强大而导致效率低,(很多时候,功能越强大的东西越臃肿),而我们使用的输入输出外挂既然叫外挂,那说明其一定有很大的优势,而这方面优势就体现在术有专攻上。原来的输入输出函数因为要应对不同类型的输入输出,所以内部一定做了很多的判断,而我们在遇见实际问题时,往往都是对特定类型的进行输入输出,所以这些判断就显得无用且浪费资源。这时,我们的输入输出外挂也就有了存在的必要性,也就应运而生。

我们都知道,scanf()、printf()、cin、cout其实就是对其他一些基础的获取或输出语句(getchar() putchar()等)进行封装,而这些基础的函数功能弱,效率高,所以我们的输入输出外挂也是仿照着scanf()、printf()、cin、cout来实现的,只不过做了针对性的改造,最终我们改造出来多种功能比scanf()等弱、比getchar()等强,效率比scanf()等高、比gerchar()等低的函数,从而达到针对性的作用,减少了不必要的资源消耗。

当然输入输出外挂一般用在大量输入输出的情况下,这样性价比才高一些,否则得不偿失(牺牲了代码长度而换来了微不足道的效率提升)。
--------------------- 

适用于正整数

template <class T>
inline void scan_d(T &ret) 
{
    char c; 
    ret = 0;
    while ((c = getchar()) < '0' || c > '9');
    while (c >= '0' && c <= '9')
    { 
        ret = ret * 10 + (c - '0'), c = getchar();
    }
}



适用于正负整数

template <class T>
inline bool scan_d(T &ret) 
{
    char c; 
    int sgn;
    if (c = getchar(), c == EOF) 
    {
        return 0; //EOF 
    }
    while (c != '-' && (c < '0' || c > '9')) 
    {
        c = getchar(); 
    }
    sgn = (c == '-') ? -1 : 1;
    ret = (c == '-') ? 0 : (c - '0'); 
    while (c = getchar(), c >= '0' && c <= '9') 
    {
        ret = ret * 10 + (c - '0'); 
    }
    ret *= sgn;
    return 1;
}

template <class T>
inline void print_d(T x) 
{ 
    if (x > 9) 
    {
        print_d(x / 10); 
    }
    putchar(x % 10 + '0');
}


仅适合纯数字输入输出

int Scan()
{   //  输入外挂  
    int res = 0, flag = 0;  
    char ch;  
    if ((ch = getchar()) == '-') 
    {   
        flag = 1;  
    }    
    else if(ch >= '0' && ch <= '9') 
    {
        res = ch - '0'; 
    }
    while ((ch = getchar()) >= '0' && ch <= '9')  
    {
        res = res * 10 + (ch - '0');  
    }
    return flag ? -res : res;  
}  

void Out(int a) 
{   //  输出外挂  
    if (a < 0) 
    {
        putchar('-');
        a = -a;
    }  
    if (a >= 10)
    {
       Out(a / 10);  
    }
    putchar(a % 10 + '0');  
}  

int main() 
{  
    int T, n;  
    scanf ("%d", &T);  
    while (T--) 
    {  
        n = Scan();  
        Out(n);  
        printf("\n");  
    }  
    return 0;  
}



适用于正负数(int,long long,float,double)

template <class T>
bool scan_d(T &ret)
{
    char c; 
    int sgn; 
    T bit = 0.1;
    if (c=getchar(), c==EOF) 
    {
        return 0;
    }
    while (c! = '-' && c != '.' && (c < '0' || c > '9')) 
    {
        c = getchar();
    }
    sgn = (c == '-') ? -1 : 1;
    ret = (c == '-') ? 0 : (c - '0');
    while (c = getchar(), c >= '0' && c <= '9')
    {
        ret = ret * 10 + (c - '0');
    }
    if (c == ' ' || c == '\n')
    {
        ret *= sgn;
        return 1;
    }
    while (c = getchar(), c >= '0' && c <= '9')
    {
        ret += (c - '0') * bit, bit /= 10;
    }
    ret *= sgn;
    return 1;
}

template <class T>
inline void print_d(int x)
{
    if (x > 9)
    {
        print_d(x / 10);
    }
    putchar(x % 10 + '0');
}



套装

char buf[MAXIN], *ps = buf, *pe = buf + 1;

inline void rnext()
{
    if (++ps == pe)
    {
        pe = (ps = buf) + fread(buf, sizeof(char), sizeof(buf) / sizeof(char), stdin);
    }
    return ;
}

template <class T>
inline bool in(T &ans)
{
    ans = 0;
    T f = 1;
    if (ps == pe)
    {
        return false;
    }
    do
    {
        rnext();
        if ('-' == *ps)
        {
            f = -1;
        }
    } while (!isdigit(*ps) && ps != pe);
    if (ps == pe)
    {
        return false;
    }
    do
    {
        ans = (ans << 1) + (ans << 3) + *ps - 48;
        rnext();
    } while (isdigit(*ps) && ps != pe);
    ans *= f;
    return true;
}

char bufout[MAXOUT], outtmp[50], *pout = bufout, *pend = bufout + MAXOUT;

inline void write()
{
    fwrite(bufout, sizeof(char), pout - bufout, stdout);
    pout = bufout;
    return ;
}

inline void out_char(char c)
{
    *(pout++) = c;
    if (pout == pend)
    {
        write();
    }
    return ;
}

inline void out_str(char *s)
{
    while (*s)
    {
        *(pout++) = *(s++);
        if (pout == pend)
        {
            write();
        }
    }
    return ;
}

template <class T>
inline void out_int(T x)
{
    if (!x)
    {
        out_char('0');
        return ;
    }
    if (x < 0)
    {
        x = -x, out_char('-');
    }
    int len = 0;
    while (x)
    {
        outtmp[len++] = x % 10 + 48;
        x /= 10;
    }
    outtmp[len] = 0;
    for (int i = 0, j = len - 1; i < j; i++, j--)
    {
        swap(outtmp[i], outtmp[j]);
    }
    out_str(outtmp);
    return ;
}



其他
上面那个输入正负整数的有点难用。 
再附一个:

void in(int &m)
{
    char ch;
    int flag = 0;
    while ((ch = getchar()) < '0' || ch > '9')
    {
        if (ch == '-')
        {
            flag = 1;
        }
    }
    for (m = 0; ch >= '0' && ch <= '9'; ch = getchar())
    {
        m = m * 10 + ch - '0';
    }
    if (flag)
    {
        m *= -1;
    }
}

 

struct FastIO
{
    static const int S = 100 << 1;

    int wpos;
    char wbuf[S];

    FastIO() : wpos(0) {}

    inline int xchar()
    {
        static char buf[S];
        static int len = 0, pos = 0;

        if (pos == len)
        {
            pos = 0;
            len = (int)fread(buf, 1, S, stdin);
        }
        if (pos == len)
        {
            return -1;
        }

        return buf[pos++];
    }

    inline int xint()
    {
        int s = 1, c = xchar(), x = 0;
        while (c <= 32)
        {
            c = xchar();
        }
        if (c == '-')
        {
            s = -1;
            c = xchar();
        }
        for (; '0' <= c && c <= '9'; c = xchar())
        {
            x = x * 10 + c - '0';
        }

        return x * s;
    }

    ~FastIO()
    {
        if (wpos)
        {
            fwrite(wbuf, 1, wpos, stdout);
            wpos = 0;
        }
    }
} io;



添加 FastIOstrtok和sscanf结合输入

/*
 *  空格作为分隔输入,读取一行的整数
 */
gets(buf);

int v;
char *p = strtok(but, " "); 
while (p)
{
    sscanf(p, "%d", &v);
    p = strtok(NULL," "); 
}

1. 一般输入输出挂

template <typename T>  
inline bool scan_d (T &ret) {  
    char c;  
    int sgn;  
    if (c = getchar(), c == EOF) return 0; //EOF  
    while (c != '-' && (c < '0' || c > '9') ) {
        if((c = getchar()) == EOF) return 0;
    }
    sgn = (c == '-') ? -1 : 1;  
    ret = (c == '-') ? 0 : (c - '0');  
    while (c = getchar(), c >= '0' && c <= '9') ret = ret * 10 + (c - '0');  
    ret *= sgn;  
    return 1;  
}  
template<typename T>
void print(T x) {
    static char s[33], *s1; s1 = s;
    if (!x) *s1++ = '0';
    if (x < 0) putchar('-'), x = -x;
    while(x) *s1++ = (x % 10 + '0'), x /= 10;
    while(s1-- != s) putchar(*s1);
}
template<typename T>
void println(T x) {
    print(x); putchar('\n');
}


2. 加强版输入输出挂
原理是将数据一次性全部读入到内存中。

namespace IO {
    const int MT = 10 * 1024 * 1024;  /// 10MB 请注意输入数据的大小!!!
    char IO_BUF[MT];
    int IO_PTR, IO_SZ;
    /// 要记得把这一行添加到main函数第一行!!!
    void begin() {
        IO_PTR = 0;
        IO_SZ = fread (IO_BUF, 1, MT, stdin);
    }
    template<typename T>
    inline bool scan_d (T & t) {
        while (IO_PTR < IO_SZ && IO_BUF[IO_PTR] != '-' && (IO_BUF[IO_PTR] < '0' || IO_BUF[IO_PTR] > '9'))
            IO_PTR ++;
        if (IO_PTR >= IO_SZ) return false;
        bool sgn = false;
        if (IO_BUF[IO_PTR] == '-') sgn = true, IO_PTR ++;
        for (t = 0; IO_PTR < IO_SZ && '0' <= IO_BUF[IO_PTR] && IO_BUF[IO_PTR] <= '9'; IO_PTR ++)
            t = t * 10 + IO_BUF[IO_PTR] - '0';
        if (sgn) t = -t;
        return true;
    }
    inline bool scan_s (char s[]) {
        while (IO_PTR < IO_SZ && (IO_BUF[IO_PTR] == ' ' || IO_BUF[IO_PTR] == '\n') ) IO_PTR ++;
        if (IO_PTR >= IO_SZ) return false;
        int len = 0;
        while (IO_PTR < IO_SZ && IO_BUF[IO_PTR] != ' ' && IO_BUF[IO_PTR] != '\n')
            s[len ++] = IO_BUF[IO_PTR], IO_PTR ++;
        s[len] = '\0';
        return true;
    }
    template<typename T>
    void print(T x) {
        static char s[33], *s1; s1 = s;
        if (!x) *s1++ = '0';
        if (x < 0) putchar('-'), x = -x;
        while(x) *s1++ = (x % 10 + '0'), x /= 10;
        while(s1-- != s) putchar(*s1);
    }
    template<typename T>
    void println(T x) {
        print(x); putchar('\n');
    }
};