Here you have a loop that reads up to MAXBUFFERSIZE characters from the input into buffer[]:
Originally Posted by
jinjiro
Code:
userIn = getchar();
char_count = 0;
while((userIn != '\n') && (char_count < MAXBUFFERSIZE)) { //avoid user from entering invalid input type
buffer[char_count++] = userIn;
userIn = getchar();
}
You don't check for end of file, userIn == EOF. This means that if the user presses Ctrl-D (in Linux/Mac, Ctrl-Z in Windows, I think), your buffer will just be filled with garbage ((char)EOF, typically 0xFF.)
Why don't you do
Code:
char *input_line;
size_t input_len;
input_line = fgets(buffer, sizeof buffer, stdin);
if (input_line == NULL) {
/* No more input! */
break;
}
instead? Getting NULL from fgets() is the same as getting EOF from getchar() .
Furthermore, you can then remove leading and trailing whitespace and newlines, and find out the input line length by using
Code:
input_line += strspn(input_line, "\t\n\v\f\r "); /* Skip over whitespace */
input_len = strcspn(input_line, "\n\r"); /* Length until newline or end-of-string */
input_line[input_len] = '\0'; /* Terminate, in case input_len ended with a newline. */
Both strcspn() and strspn() are standard C functions. The links tell you more.
Originally Posted by
jinjiro
Code:
printf("\n\n\nRun application again (Y/N)?");
scanf(" %c",&optExit);
optExitUpper = toupper(optExit);
Here, you scan for a single character from the standard input. This does not consume the newline that will be in the standard input (as the user must press Enter, there will be a newline in the input). Therefore, on the second run, your earlier read loop will first read the newline, and read nothing.
To request confirmation, I'd recommend using a loop, such as
Code:
do {
printf("\n\n\nRun application again (Y/N)?");
fflush(stdout);
/* Read a line of input. */
input_line = fgets(buffer, sizeof buffer, stdin);
if (input_line == NULL) {
/* No more input. Act as if the user said N. */
input_line = buffer;
input_line[0] = 'N';
input_line[1] = '\0';
} else {
/* Skip leading whitespace and newlines. */
input_line += strspn(input_line, "\t\n\v\f\r ");
}
} while (input_line[0] != 'Y' && input_line[0] != 'y' &&
input_line[0] != 'N' && input_line[0] != 'n');
As to the overall structure:
Code:
/* "application" loop */
do {
do {
/* TODO: Ask the user for the base */
/* TODO: read line */
/* TODO: parse line to 'base' */
} while (base < 2);
/* No input? break in above do {} while() loop? */
if (!input_line)
break;
do {
/* TODO: ask the user for data to convert */
/* TODO: read line */
/* Empty line ends data loop */
if (line_len < 1)
break;
/* TODO: parse line */
/* TODO: convert */
/* TODO: output results */
/* Repeat forever (unless break above) */
} while (1);
/* No more input, break in above do {} while () loop? */
if (!input_line)
break;
do {
printf("\n\n\nRun application again (Y/N)?");
fflush(stdout);
/* Read a line of input. */
input_line = fgets(buffer, sizeof buffer, stdin);
if (input_line == NULL) {
/* No more input. Act as if the user said N. */
input_line = buffer;
input_line[0] = 'N';
input_line[1] = '\0';
} else {
/* Skip leading whitespace and newlines. */
input_line += strspn(input_line, "\t\n\v\f\r ");
}
} while (input_line[0] != 'Y' && input_line[0] != 'y' &&
input_line[0] != 'N' && input_line[0] != 'n');
} while (input_line[0] == 'Y' || input_line[0] == 'y');
Originally Posted by
jinjiro
Another question is about loop in the code below.
1. Only ask one question per post.
2. Don't do string magick on numbers. There are easier ways to do that.
Code:
assuming unsigned int or unsigned long number:
number % 10U gives you the first, rightmost digit
(number / 1U) % 10U also gives you the first, rightmost digit
(number / 10U) % 10U gives you the seconds digit (tens)
(number / 100U) % 10U gives you the third digit (hundreds)
and so on.
You can even loop over the digits (from right to left) using
Code:
unsigned int number = nonnegative number whose digits we are interested in;
unsigned int divisor = 1U;
unsigned int position = 0; /* Rightmost */
unsigned int digit;
do {
digit = number % 10U;
/* We now have 0 <= digit && digit < 10.
* TODO: Do something with digit (and possibly position).
*/
/* Divide number by ten, and advance position indicator */
number /= 10U;
position++;
/* Loop for as long as we have digits left */
} while (number);
Now, it just so happens that decimal system is just base-10. So, if you were to change the number 10 (10U meaning unsigned-integer ten) to any integer larger than one, it would work for that base too. Just remember it goes from right to left; I included the position so it'll start from 0 (rightmost) upwards (left).