Reputation: 37
The current problem is with the Evaluate another interval (Y/N)?
prompt. Let's say I run the program 4 times; in order to end it, it requires me to type N
4 times.
int main() {
int trap, test;
double low, hi;
char repeat, c;
//Gather End Points
do {
printf("Enter endpoints of interval to be integrated (low hi): ");
test = scanf("%lf %lf", &low, &hi);
if (test != 2) {
printf("Error: Improperly formatted input\n");
while((c = getchar()) != '\n' && c != EOF); //Discard extra characters
} else
if (low > hi)
printf("Error: low must be < hi\n");
} while ((test != 2 || low > hi));
//Gather amount of triangles
do {
printf("Enter number of trapezoids to be used: ");
test = scanf("%d", &trap);
if (test != 1) {
printf("Error: Improperly formated input\n");
while((c = getchar()) != '\n' && c != EOF); //Discard extra characters
} else
if (trap < 1)
printf("Error: numT must be >= 1\n");
} while ((trap < 1 || test != 1));
//Output integrate
printf("Using %d trapezoids, integral between %lf and %lf is %lf",
trap, low, hi, integrate(low, hi, trap));
//Prompt user for another time
while (1) {
printf("\nEvaluate another interval (Y/N)? ");
scanf(" %c", &repeat);
switch (repeat) {
case 'Y':
main();
case 'y':
main();
case 'N':
return 0;
case 'n':
return 0;
default:
printf("Error: must enter Y or N");
}
}
return 0;
}
I expect it so that no matter what run of the program I'm on it will close when I type one N
.
Upvotes: 0
Views: 109
Reputation: 144655
There are multiple problems in your program:
scanf()
when reading the user's answer to the prompts, and you clear the pending input correctly, but you do not handle the potential end of file, leading to endless loops.c
must be defined as int
to accommodate for all values returned by getchar()
: 256 values of type unsigned char
and the special value EOF
.main()
recursively to repeat the program's action requiring multiple N
answers. You should instead add an outer loop and exit from it upon a N
answer or an end of file condition.Here is a modified version:
#include <stdio.h>
double integrate(double low, double hi, int trap) {
...
}
int flush_line(void) {
// Consume the pending input and return `'\n`` or `EOF`
int c;
while ((c = getchar()) != EOF && c != '\n')
continue;
return c;
}
int main() {
// Main program loop
for (;;) {
int trap, test;
double low, hi;
char repeat;
//Gather End Points
for (;;) {
printf("Enter endpoints of interval to be integrated (low hi): ");
test = scanf("%lf %lf", &low, &hi);
if (test == EOF)
return 1;
if (test != 2) {
printf("Error: Improperly formatted input\n");
if (flush_line() == EOF)
return 1;
continue; // ask again
}
if (low > hi) {
printf("Error: low must be < hi\n");
continue;
}
break; // input is valid
}
//Gather amount of triangles
for (;;) {
printf("Enter number of trapezoids to be used: ");
test = scanf("%d", &trap);
if (test == EOF)
return 1;
if (test != 1) {
printf("Error: Improperly formated input\n");
if (flush_line() == EOF)
return 1;
continue;
}
if (trap < 1) {
printf("Error: numT must be >= 1\n");
continue;
}
break;
}
//Output integrate
printf("Using %d trapezoids, integral between %lf and %lf is %lf\n",
trap, low, hi, integrate(low, hi, trap));
//Prompt user for another time
for (;;) {
printf("\nEvaluate another interval (Y/N)? ");
if (scanf(" %c", &repeat) != 1)
return 1; // unexpected end of file
switch (repeat) {
case 'Y':
case 'y':
break;
case 'N':
case 'n':
return 0;
default:
printf("Error: must enter Y or N\n");
if (flush_line() == EOF)
return 1;
continue;
}
break;
}
}
}
Upvotes: 0
Reputation: 44264
There are many ways to achieve what you want but calling main
recursively is not a good idea.
A pretty simple way to change your program is to add an additional while(1)
level. Something like:
int main(void)
{
char repeat;
while(1){ // Outer while to keep the program running
printf("running program\n");
// Put your program here
printf("program done\n");
repeat = '?';
while(repeat != 'y' && repeat != 'Y'){ // Repeat until input is 'Y' or 'y'
printf("\nEvaluate another interval (Y/N)? ");
scanf(" %c", &repeat);
switch (repeat){
case 'Y':
case 'y':
break;
case 'N':
case 'n':
return 0; // Stop if input is 'n' or 'N'
default:
printf("Error: must enter Y or N");
}
}
}
return 0; // This will never be reached
}
Another way (a simpler way, IMO) is to put the code where you ask the user into a function that you call from main
. Like:
int continueProg()
{
char repeat = '?';
while(1){
printf("\nEvaluate another interval (Y/N)? ");
scanf(" %c", &repeat);
switch (repeat){
case 'Y':
case 'y':
return 1;;
case 'N':
case 'n':
return 0;
default:
printf("Error: must enter Y or N");
}
}
}
int main(void)
{
do {
printf("running program\n");
// Put your program here
printf("program done\n");
} while(continueProg());
return 0;
}
BTW: Take a look at getchar
instead of using scanf
Upvotes: 1