1. ## Catching user errors

Hi guys,

I'm writing a program that calculates resistance values from the colour codes. My program works fine, but I am having trouble catching user errors.

My program should print an error message, when the user enters an invalid value, then prompt the user to try again.

Basically, my question is how to implement this. I tried using while loops, but ended up with an infinite loop of error messages and user prompts.

I'm not looking for people to do my homework, but can somebody show me an example of a loop that catches errors?

Here is my code:
Code:
```#include <stdio.h>
#include <math.h>
void main()

{
int   user_choice, choice1, choice2, choice3, choice4, band_1, band_2;
int band_3, band_4;
float resistance;

printf("\t 1. Calculate resistance\n");
printf("\t 2. Help\n");
printf("\t 3. EXIT\n");

do
{
printf("Enter Selection:");
scanf("%d", &user_choice);
}while (user_choice !=1 && user_choice!=2 && user_choice!=3);
if (user_choice==1)
{
printf("\nPlease enter the colour of the first band\n");
printf("1 for Black\t 2 for Red\t 3 for Brown\n");
printf("4 for Orange\t 5 for Yellow\t 6 for Green\n");
printf("7 for Blue\t 8 for Violet\t 9 for Gray\n");
printf("10 for White.\n");
scanf("%d", &choice1);

if (choice1==1)
{
band_1=0;
}
if (choice1==2)
{
band_1=1;
}
if (choice1==3)
{
band_1=2;
}
if (choice1==4)
{
band_1=3;
}
if  (choice1==5)
{
band_1=4;
}
if (choice1==6)
{
band_1=5;
}
if (choice1==7)
{
band_1=6;
}
if (choice1==8)
{
band_1=7;
}
if (choice1==9)
{
band_1=8;
}
if (choice1==10)
{
band_1=9;
}
printf("\nPlease enter the colour of the second band\n");
printf("1 for Black\t 2 for Red\t 3 for Brown\n");
printf("4 for Orange\t 5 for Yellow\t 6 for Green\n");
printf("7 for Blue\t 8 for Violet\t 9 for Gray\n");
printf("10 for White.\n");
scanf("%d", &choice2);

if (choice2==1)
{
band_2=0;
}
if (choice2==2)
{
band_2=1;
}
if (choice2==3)
{
band_2=2;
}
if (choice2==4)
{
band_2=3;
}
if  (choice2==5)
{
band_2=4;
}
if (choice2==6)
{
band_2=5;
}
if (choice2==7)
{
band_2=6;
}
if (choice2==8)
{
band_2=7;
}
if (choice2==9)
{
band_2=8;
}
if (choice2==10)
{
band_2=9;
}

printf("\nPlease enter the colour of the third band\n");
printf("1 for Black\t 2 for Red\t 3 for Brown\n");
printf("4 for Orange\t 5 for Yellow\t 6 for Green\n");
printf("7 for Blue\t 8 for Violet\t 9 for Gray\n");
printf("10 for White\t 11 for Gold\t 12 for Silver\n");
scanf("%d", &choice3);
if (choice3==1)
{
band_3=0;
}
if (choice3==2)
{
band_3=1;
}
if (choice3==3)
{
band_3=2;
}
if (choice3==4)
{
band_3=3;
}
if  (choice3==5)
{
band_3=4;
}
if (choice3==6)
{
band_3=5;
}
if (choice3==7)
{
band_3=6;
}
if (choice3==8)
{
band_3=7;
}
if (choice3==9)
{
band_3=8;
}
if (choice3==10)
{
band_3=9;
}
if (choice3==1)
{
band_3=-1;
}
if (choice3==12)
{
band_3=-2;
}

resistance=((band_1*10)+band_2)*pow(10, band_3);

if (resistance >=1000.0 && resistance<100000.0)
{
resistance=resistance/1000.0;
printf("\nThe resistance is %f kilo Ohms", resistance);
}
if (resistance>=1000000.0 && resistance<1000000000.0)
{
resistance=resistance/1000000;
printf("\nThe resistance is %f Mega Ohms");
}
printf("\n\nthis is the resistance %f ohms", resistance);
}

if (user_choice==2)
{
printf("To use this program enter the resistor colour codes using the numbers 1-12\n");
}
if (user_choice==3)
{
printf("Good day");
}

}```
Thank you,

-cda67

3. Several things:
Code:
`void main()`
That should be int main(void), and return an int at the end, typically 0 for success. Read this link and this link.
Code:
```        if (choice1==1)
{
band_1=0;
}
if (choice1==2)
...```
Those are not mutually exclusive, which makes error checking a pain. If you used if...else if... you could use a final else to catch an error, but it would still be highly inefficient. Better yet:
Code:
```if (choice1 < 1 || choice1 > 10) {
// error
}
else {
band_1 = choice1 - 1;  // notice the relationship, the band value is always one less than the choice value, do likewise for band 2
}```
Also, notice how you do exactly the same thing for choice 1 and 2. Ideally, you would put all the code to display choices, read a value and check for error in a function, and maybe use an array to store the band values. If you haven't learned about functions or arrays yet, don't worry. If you have, then use them!

Lastly, you may want a second do while loop to encompass everything, otherwise, you can only calculate resistance or get help once before your program quits.

4. Alright, I've tried to make my program simpler, but still getting some infinite loops instead of error messages.
Code:
```#include <stdio.h>
#include <math.h>

void main()

{
char error_bell = 7;
int   user_choice, choice4, band_1, band_2;
int band_3, band_4;
float resistance;
while (user_choice!=3)      /*This while loop is there so that the user will be returned to the main prompt after reading the help */
{
printf("\t 1. Calculate resistance\n");
printf("\t 2. Help\n");
printf("\t 3. EXIT\n");

//while (user_choice!=1 || user_choice!=2 || user_choice!=3)
//{

printf("\nEnter selection:");
scanf("%d", &user_choice);

//}

if (user_choice==1)
{
printf("\nPlease enter the colour of the first band\n");
printf("0 for Black\t 1 for Red\t 2 for Brown\n");
printf("3 for Orange\t 4 for Yellow\t 5 for Green\n");
printf("6 for Blue\t 7 for Violet\t 8 for Gray\n");
printf("9 for White.\n");
scanf("%d", &band_1);

printf("\nPlease enter the colour of the second band\n");
printf("0 for Black\t 1 for Red\t 2 for Brown\n");
printf("3 for Orange\t 4 for Yellow\t 5 for Green\n");
printf("6 for Blue\t 7 for Violet\t 8 for Gray\n");
printf("9 for White.\n");
scanf("%d", &band_2);

printf("\nPlease enter the colour of the third band\n");
printf("0 for Black\t 1 for Red\t 2 for Brown\n");
printf("3 for Orange\t 4 for Yellow\t 5 for Green\n");
printf("6 for Blue\t 7 for Violet\t 8 for Gray\n");
printf("9 for White\t -1 for Gold\t -2 for silver.\n");
scanf("%d", &band_3);

printf("\nPlease enter the colour of the fourth band\n");
printf("1 for Gold\t 2 for Silver");
scanf("%d", &choice4);

if (choice4==1)
band_4 = 5;
if (choice4==2)
band_4 = 10;

resistance=((band_1*10)+band_2)*pow(10, band_3);
if (resistance < 1000.0)
printf("\nThis is the resistance %f ohms +- %d percent error\n\n", resistance, band_4);

if (resistance >=1000.0 && resistance<1000000.0)
{
resistance=resistance/1000.0;
printf("\nThe resistance is %f kilo Ohms +- %d percent error\n\n", resistance, band_4);
}
if (resistance>=1000000.0 && resistance<1000000000.0)
{
resistance=resistance/1000000.0;
printf("\nThe resistance is %f Mega Ohms +- %d percent error\n\n", resistance, band_4);
}
}

if (user_choice==2)
printf("\nTo use this program, simply input the number corresponding to the colour on the resistor\n.");

if (user_choice==3)
{
printf("\nGood day!");
}
//else
//printf("Invalid input\n");
}
}```

5. I forgot to link you to the articles on main, so here they are (you still should have taken my advice there): Cprogramming.com FAQ > main() / void main() / int main() / int main(void) / int main(int argc, char *argv[]) and void main(void) - the Wrong Thing. Other than that your new code is much better. The only thing I would do as an improvement is this:
Code:
```if (user_choice == 1) {
}
else if user_choice == 2) {
print help message
}
else if (user_choice == 3) {
say good bye
}
else {
print invalid input
}```
Notice the use of the "else if" construct.

The calculations appear to be correct, so that is fine.

As for the infinite loops, I can't replicate them with your new code. What input are you giving that causes infinite loops?

6. That else if structure really helped, and I changed my 'void main' to 'int main(void)'. I got the infinite loops when I inputed a character value, for instance 'ghdjj.' Integer error messages are caught and dealt with, but any other characters cause problems.

If you want a noob programming story to laugh at: I wanted to print the bell sound to go along with an error, and I accidentally inputed a char value, which caused the program to go into an infinite loop of bell sounds that even crtl-alt-del couldnt fix.

7. Hahaha! I've done something quite similar when I was a noob. Anyhow, that's because you use scanf, which only accepts integers. Try reading a line into a char buffer with fgets, then using sscanf to get an integer from that buffer. Make sure you check the return value of sscanf to make sure there's an integer in there. Check these two FAQ articles for examples:
Cprogramming.com FAQ > Validate user input
Cprogramming.com FAQ > Get a line of text from the user/keyboard (C)