/*
 * program to get integer from input, maybe more nicely than scanf
 *
 * version from 9/26 class with a few improvements. 
 * ("vimdiff -o getint.c getint-improved.c" to show differences)
 */
#include <stdio.h>

int getint(int *result_p);
char first_non_blank();
int collect_digits(char first, int digits_to_left, int *result_p);
int char_to_digit(char c);

int main(void) {
	int result;
	printf("enter an integer\n");
	if (getint(&result) == 0) {
		printf("%d\n", result);
	}
	else {
		printf("error\n");
	}
	return 0;
}

/*
 * get integer from stdin
 * returns 0 on success, something else on error
 */
int getint(int *result_p) {

	/* skip over leading blanks */
	char first = first_non_blank();

	int sign = 1;

	/* negative */
	if (first == '-') {
		sign = -1;
		first = getchar();
	}

	/* first nonblank is not a digit */
	else if (first < '0' || first > '9') {
		return 1;
	}

	/* first nonblank is a digit */
	int status = collect_digits(first, 0, result_p);
	if (status == 0) {
		*result_p *= sign;
	}
	return status;
}

/* 
 * get first nonblank from stdin 
 */
char first_non_blank() {
	char ch = getchar();
	if (ch != ' ') {
		return ch;
	}
	else {
		return first_non_blank();
	}
}

/*
 * collect digits from stdin and turn into integer, until first blank
 *   or end of line is reached
 * returns 0 on success, something else on error
 */
int collect_digits(char first, int digits_to_left, int *result_p) {
	if (first == ' ' || first == '\n') {
		*result_p = digits_to_left;
		return 0;
	}
	else if (first < '0' || first > '9') {
		return 1;
	}
	else {
		return collect_digits(
				getchar(), digits_to_left*10 + char_to_digit(first), result_p);
	}
}

int char_to_digit(char c) {
	return c-'0';
}