Fread - 大量整数
Fread - large amount of integers
我需要从标准输入读取大量整数。速度在这里很重要,例如 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
我需要从标准输入读取大量整数。速度在这里很重要,例如 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