c - Fread - 大量整数

标签 c optimization fread

我需要从标准输入读取大量整数。速度在这里非常重要,例如 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;
}

最佳答案

// 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

关于c - Fread - 大量整数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28865674/

相关文章:

c - 如何在单独的线程中传递 blt vector

无法使用 fscanf 读取此文件

c - GCC 编译时浮点优化

python - 谁能教我如何进一步优化这个 'print up to the nth prime number' 脚本?

c++ - fread 在 64 位 iOS 上无法正常工作

c - 从 .txt 文件中读取 2 个字节

PHP readfile/fgets/fread 导致对服务器的多次请求

C4996 'scanf' : This function or variable may be unsafe. 考虑改用 scanf_s。要禁用弃用,请使用 _CRT_SECURE_NO_WARNINGS

php - 在数据库表中存储大量数据的最佳实践

c - C 中 undefined reference