Fread - 大量的整数

时间:2015-03-04 21:48:08

标签: c optimization fread

我需要从stdin中读取大量的整数。速度在这里非常重要,例如getchar_unlocked对我来说太慢了(百分之一秒真的很重要)

我的代码适用于getchar_unlocked,但是现在我试图读取未知数量的整数行以缓冲fread。那里出了什么问题?

以下代码:

inline int fastRead_int(int *sum) {

char buffer[sizeof(int)*sizeof(int)];
register int i = 0;
fread(buffer,sizeof(buffer),1,stdin);
register int c = buffer[0];
int x = 0;

while(c != NULL)
{
    c = buffer[++i];
    for(; ((c<48 || c>57) && c != ' '); c = buffer[++i]);


for(; c>47 && c<58 && c != ' ' ; c = buffer[++i]) {
    x = (x<<1) + (x<<3) + c - 48;
}

*sum = *sum+x;
}

1 个答案:

答案 0 :(得分:0)

// what exactly does the input look like?
// I doubt that the input is a series of single digit numbers.
// and for multidigit numbers, the following will not work

// the posted code fails to compile for several reasons, 
// including that the 'int' return value is never set
// and the code is much to big for inlining

inline int fastRead_int(int *sum) 
{

    char buffer[sizeof(int)*sizeof(int)]; //<-- = 64bytes = 16 binary ints
                                          //      but as little as 4 character ints
    register int i = 0;

    fread(buffer,sizeof(buffer),1,stdin);
         // <-- should check/save the returned value
         //     as that would be the number of characters actually read
         //     and fread() does not NUL terminate the input
         //     should also check for and handle read failures

    register int c = buffer[0];    // <-- this gets one byte/char only, 
                                   // however, unless the input is a binary file
                                   //          this will only get the first byte
                                   //          of a numeric char string.
    int x = 0;

    // <-- suggest the following code block be:
    //     for( i=0; i<(returned value from fread(); i++)
    //     {
    //         if( isdigit(c) )
    //         {
    //             x += (c-48);
    //         }
    //         c = buffer[++i];
    //      } // end for
    //      *sum += x;
    while(c != NULL) // <-- 'c' is a integer in the range 0...255
                     //     but NULL is a 4 byte pointer to 0
                     //     perhaps you meant: 'while(c)'
    {
        c = buffer[++i];  // <-- see my comment about reading buffer, above

        // step by non-numeric characters
        // what if the input does not end in a numeric character?
        //      then would be reading past the end of the buffer[]
        //      resulting in undefined behaviour leading to a seg fault event
        for(; ((c<48 || c>57) && c != ' '); c = buffer[++i]);
            //<-- much better/clearer to #include ctype.h and then
            //    for( ; !isdigit(c); c = buffer[++i] ;)

        // <-- see above comments
        for(; c>47 && c<58 && c != ' ' ; c = buffer[++i]) 
        {
            x = (x<<1) + (x<<3) + c - 48;
        }

        *sum = *sum+x;
    } // end while