I decided to rewrite this post, previously has been deleted.
I know there a many of posts low-level i/o.
scanf/printf solves slowly i/o, partially, but not always.
Most generic usage i/o — is read and write integers, so I'll write about it without a hundred lines of source code.
1. Read integers.
For simplicity, all input file content loaded to a big buffer, and it will be parsed.
char in[1<<23] ; // a big buffer
char const* o ; // pointer to buffer.
And for detecting end of buffer, put '\0' — terminating symbol to end of buffer ( as plain c-string).
Now loading the file:
void load(){ o = in; in [ fread(in, 1, sizeof(in ) - 4 , stdin ) ] = 0; }
fread - returns number of reading symbols, we just use this for put '\0' terminating symbol to end of buffer.
Reading a unsigned integer:
unsigned readUInt(){
unsigned u = 0;
while( *o && *o <= 32) ++o ; // skip spaces
while ( *o >='0' && *o <='9') u = (u << 3) + (u << 1) + (*o++ -'0');
return u;
}
By default most implementations used u = u * 10 + (*o++ - '0')
,
but u * 10 = u * 8 + u * 2 = (u << 3) + (u <<1)
I don't know it gives speed, but with shifting the code become happy :)
Reading signed integer.
Some theory of signed integer representation, in most situation see here
-u == ~u + 1
There ~ — bitwise inverting.
And ~u == u ^ 0xFFFFFFFF
or ~u == u ^ ~0
Let start writing method
int readInt()
{
unsigned u = 0, s = 0; // s = 0, if integer positive, s = ~0 - if integer negative
while(*o && *o <= 32)++o; // skip spaces
if (*o == '-')s = ~0, ++o; else if (*o == '+') ++o; // determine sign
while( *o >='0' && *o <= '9') u = (u << 3) + (u << 1) + (*o ++ - '0');
return (u^s) + !!s; // ??????? : s = 0 : (u^s) + !!s = (u^0) + !!0 = u + 0 = u, and
// s = ~0: (u^s) + !!s = (u ^ ~0) + !! ~0 = (u^0xFFFFFFFF) + 1 = ~u + 1 = -u
}
How to use this complete?
#include <cstdio>
char const * o;
char in[1<<23];
void load(){ o = in ; in [ fread(in,1,sizeof(in)-4,stdin)] = 0; }
unsigned readUInt(){
unsigned u = 0;
while(*o && *o <= 32)++o;
while(*o >='0' && *o <='9') u = (u << 3) + (u << 1) + (*o++ -'0');
return u;
}
int readInt(){
unsigned u = 0, s = 0;
while(*o && *o <= 32)++o;
if (*o == '-') s = ~0, ++o; else if(*o == '+') ++o;
while(*o >='0' && *o <='9') u = (u << 3) + (u << 1) + (*o++ - '0');
return (u ^ s) + !!s;
}
int main()
{
load();
int n = readInt();
int s = 0;
for(int i= 0; i < n; ++i)s += readInt();
printf("summa = %d\n", s);
return 0;
}
Benchmark: read and write 10^6 numbers took 120~150 milliseconds where scanf/printf ~650 milliseconds.
for competetive programming I suggest this one method:
typedef long long ll;
typedef unsigned long long ull;
ll readInt(){
ull u = 0 , s = 0;
while(*o && *o <= 32)++o;
if (*o == '-') s = ~s, ++o; else if (*o == '+') ++o;
while(*o >='0' && *o<='9') u = (u << 3) + (u << 1) + (*o++ -'0');
return (u ^ s) +!!s;
}
WRITing methods will be soon.