This is a follow-up review of Calculate the sum of interior angles of a polygon.
Using the helpful answers from the original post, I have integrated the suggestions which are in order from first to last:
- Adding checks to
scanf()
. - Using
main(void)
in place ofmain(...)
. - Passing
char *
directly toprintf()
. - Made conditionals simpler.
main()
is broken up into several functions and subroutines.
I am seeking a second peer review because I have also added changes not suggested in the original post which are:
- Using enumerations to convey error information.
- Heavier error-checking in function
askAgain()
.
#include <stdio.h>
#include <string.h>
#include <stdbool.h>
/* Keep string constants of the questions. */
const char* howManySides =
"How many sides does the shape have? ";
const char* askAnotherShape =
"Would you like to find interior angles for another polygon? (0 or 1) ";
/* Table of polygon names from 3 to 12 sides */
const char* names[] = {
"a triangle",
"a quadrilateral",
"a pentagon",
"a hexagon",
"a heptagon",
"an octagon",
"a nonagon",
"a decagon",
"a hendecagon",
"a dodecagon"
};
enum errorType {noError, errNegSides, errZeroSides, errInsufSides};
static int getSumInteriorAngles(const unsigned int numSides)
{
return 180 * (numSides - 2);
}
/* Print a specific type of error based on its enumeration.
*/
static void printError(const enum errorType eType)
{
switch(eType) {
case errNegSides:
printf("The number of sides cannot be negative...\n");
break;
case errZeroSides:
printf("The number of sides cannot be zero...\n");
break;
case errInsufSides:
printf("The shape must have at least 3 sides...\n");
break;
}
}
/* Takes a number of polygon sides and returns a type of error if the number
of sides invalid or no error type if the number of sides is valid.
*/
static enum errorType isSidesValid(const int numSides)
{
if(numSides < 0) return errNegSides;
else if(numSides == 0) return errZeroSides;
else if(numSides < 3) return errInsufSides;
else return noError;
}
static int getUserInput(void)
{
int userInput;
bool isValidResponse = false;
while(!isValidResponse) {
/* Ask for the number of sides. */
printf(howManySides);
/* We're looking for exactly 1 argument, so if there's
less than that, then something went wrong with the conversion. */
if(scanf("%i", &userInput) < 1) {
printf("Not a number...\n");
fflush(stdin);
/* This check failed, so repeat the question. */
continue;
}
isValidResponse = true;
}
return userInput;
}
static int getNumSides(void)
{
int numSides;
/* Initialize the checks flag to false and make it true only when
all checks pass. */
bool passedAllChecks = false;
while(!passedAllChecks) {
numSides = getUserInput();
/* If the input was a valid number, then we have to check if the
number of sides makes sense. */
enum errorType returnError = isSidesValid(numSides);
if(returnError != noError) {
/* If the number doesn't make sense for a number of sides,
then print the specific error and repeat the question. */
printError(returnError);
continue;
}
/* All checks passed. Exit the loop and return the number of sides. */
passedAllChecks = true;
}
return numSides;
}
static int askAgain(void)
{
int userResponse = 0;
bool isValidResponse = false;
while(!isValidResponse) {
printf(askAnotherShape);
/* Weed out non-integers and other weirdness. */
if(scanf("%i", &userResponse) < 1) {
printf("Not a valid response...\n");
fflush(stdin);
continue;
}
/* Restrict valid input to 0 or 1. */
if((userResponse != 0) && (userResponse != 1)) {
printf("Please choose 0 or 1...\n");
continue;
}
isValidResponse = true;
}
return userResponse;
}
static void printResult(int numSides)
{
/* Assume we're dealing with a polygon without a special name,
in which case, we'll refer to it non-specifically. */
const char *name = "this polygon";
/* If we have a name for this polygon, then get it from the table. */
if(numSides <= 12) {
name = names[numSides - 3];
}
printf("The sum of the interior angles of %s is %i\n",
name, getSumInteriorAngles(numSides));
}
int main(void)
{
do {
printResult(getNumSides());
} while(askAgain());
return 0;
}
```
)
missing while others have matching parentheses? Thanks. \$\endgroup\$