3
\$\begingroup\$

Do you have any criticisms or corrections or improvements?

I need to read only numbers(and this numbers could be from 0 to 1000000)

void fast_input(int* int_input)
  {
      *int_input=0;
       char next_char=0;
          while( next_char < '0' || next_char > '9' ){ // Skip non-digits
              next_char = getchar();
              }
              while( next_char >= '0' && next_char <= '9' )
              {
                  (*int_input) = ((*int_input)<<1) + ((*int_input)<<3) + next_char - '0';
                  next_char = getchar();
              }
 
  }
\$\endgroup\$

1 Answer 1

3
\$\begingroup\$

Do you have any criticisms or corrections or improvements?

Infinite loop

On end-of-file, first while loops loops forever.

Better code would prevent looping forever and return not void, but an indication of success.

int vs. char

getchar() returns an int and typically 257 different values. Saving in a char will lose information. Save in an int to properly distinguish EOF from other characters.

Avoid trying to out-think the compiler

A good compiler will emit optimal code.

// (*int_input) = ((*int_input)<<1) + ((*int_input)<<3) + next_char - '0';
*int_input = *int_input * 10 +  + next_char - '0';

Fast vs. I/O

Input/Output is a sink-hole of time. Significant time improvement are made there, not in trying to using < instead of *.

On return, restore last character read

To better work with other routines, it is more common to ungetc() the last non-digit read.

No overflow protection

Signed int overflow is undefined behavior (UB).

Yes, OP has "need to read only numbers(and this numbers could be from 0 to 1000000)", but that limitation is not commented in the code. So the next person lifts this code and runs into UB.

Comment important restrictions in code.

Even better, detect potential overflow

int ch = getchar();
if (*int_input >= INT_MAX/10 && 
    (*int_input > INT_MAX/10 || ch - '0' > INT_MAX%10)) {
  // Overflow!
  *int_input = INT_MAX;
} else {
  *int_input = *int_input * 10 +  + next_char - '0';
}  
   

Consider a local variable

int sum = 0;
... most of code
*int_input = sum;

Minor: 2 compares vs. isdigit()

Consider isdigit() rather than 2 compares.

Poor formatting


Alternative

Untested - but at least gives OP an idea of the above feedback.

#include <ctype.h>
#include <limits.h>

// Return EOF on end-of-file or input error without reading an int.
// Return 0 on overflow.  Value is capped.
// Return 1 on success.
// Save value read if int_input is not NULL
int fast_input_alt(int *int_input) {
  int sum = 0;
  int ch;

  // Skip non-digits
  while ((ch = getchar()) != EOF && !isdigit(ch)) {
    ;
  }

  if (ch == EOF) {
    return EOF;
  }

  int retval = 1;
  do {
    ch -= '0';
    if (sum >= INT_MAX / 10 && (sum > INT_MAX / 10 || ch > INT_MAX % 10)) {
      sum = INT_MAX;
      retval = 0;  // Overflow
    } else {
      sum = sum * 10 + ch;
    }
    ch = getchar();
  } while (isdigit(ch));

  ungetc(ch, stdin);
  if (int_input) {
    *int_input = sum;
  }
  return retval;
}
\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.