Click here to Skip to main content
15,890,882 members
Please Sign up or sign in to vote.
1.00/5 (1 vote)
See more:
in a c++ program I found this
#ifdef _WIN32
inline int getchar_unlocked() { return getchar(); }
#endif
inline int ReadInt()
{
 int c=getchar_unlocked();
 int out=0;
 while(c=='\n' || c==' ')
 c=getchar_unlocked();
 while(c!='\n' && c!=' ' && c!=-1)
 {
 out*=10;
 out+=(c-'0');
 c=getchar_unlocked();
 }
 return out;
}

in conjuction with :
{ freopen("filename.ext","rt",stdin);

every time ReadInt() is called an integer from the filename.txt is returned
eg if filename is
141
5159 55 5818
4
then 5 ReadInt()'s will give the numbers 141,5159,55,5818 and 4
my question is what the hell is this guy doing ?
is he using the standard input stream as a file stream ? and then again...getchar() returns a char from the console...
and where does this
#ifdef _WIN32
piece of code help ?( not the characted_unlocked() line..the 'if' steatement) ...this program is compiled and run on linux so why would someone do this ?

also : how can I read big (8-20 mb) files -most files contain integers only-as fast as possible without using external libraries such as the memory mapped file method ?
fscanf is way faster than ifstream but the code above is faster even than fscanf

thanks for your help :)
Posted

It is a rather old fashioned (C-style) way of reading integers from the standard input stream. The call to freopen redirects that file to stdin so it can be read with the calls to getchar. A much better way of doing it would be to use fscanf or one of the STL ifstream classes. The #ifdef _WIN32 at the top is not closed by a corresponding #endif so it's anyone's guess why it is there.
 
Share this answer
 
Comments
Vedat Ozan Oner 2-Mar-14 13:48pm    
it (#ifdef _WIN32) is closed. just below getchar_unlocked definition.
Richard MacCutchan 3-Mar-14 4:21am    
True, How did I manage to miss that?
Vedat Ozan Oner 3-Mar-14 4:34am    
it happens (mostly to me :p)
EbolaHost 2-Mar-14 14:44pm    
But this method is faster than fscanf...
And the #if is closed after two lines
Richard MacCutchan 3-Mar-14 4:22am    
Faster in terms of what? You are talking of microseconds at most, and probably a lot less, nothing that a user could ever see.
The guy is using input stream redirection in order to use getchar to perform fgetc[^] task, that is reading a character at time from a file.
In the ReadInt function, blanks and newlines are skipped, then digits are then read and used to build the resulting integer, until a blank, a newline or the end of file is found.

The key statements for building the integer from read digits are:
C++
int out=0;
 //..
while(/*...*/)
{
  out *= 10;
  out+=(c-'0');
  //..


That is out is initalised with zero, then at each step it is first multiplied by 10 and then added with the read digit value (e.g. '5' - '0' == 5).
Suppose you are reading the 55 number from the file.
  • out=0 before reading any digit
  • out is still 0 after performing the multiplication by 10
  • out=5, after performing out+=c - '0', the first time
  • out=50, after perorming out*=10 at next step
  • out=55, after performing out+=c - '0' again
  • finally a blank is detected and the function return 55


Please note, the function is not robust: it relies on the fact that every character different from a blank a newline (or the end of file) is a digit (that is not true, generally speaking, so this must be a prerequisite on your input files.
There is no overflow checking on integers (as well negative values are not correctly parsed).
Moreover it may return a spurious zero at the end of the file.
 
Share this answer
 
v2
Comments
Andreas Gieriet 2-Mar-14 16:34pm    
My 5! What you did is what the OP should have done himself: walk the code.
Cheers
Andi
CPallini 3-Mar-14 3:23am    
Thnak you.

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900