Programming in C. Data validation and converting characters into integers - c

I am making a program that includes a simple switch condition.
The problem I have encountered is that I am also validating user input so that the user cannot break the program by entering a character.
The switch works fine when I remove the isdigit() so I know it is something happening with data validation.
What I was told to do was use %c in my scanf() but if I do that then something else prevents the program from working. I suspect that it is because the switch is no longer is being referenced since the cases are 1,2,3...
The way I want to do it is just turn the character back into an integer before it reaches the switch but I am not sure how I could do that.
Something is happening when I copy and paste parts of the program so I will just paste the entire program.
#include <stdio.h>
#include <ctype.h>
int main(void)
{
int BusRoute, LTrigger;
char StartLoc,DestLoc;
LTrigger = 1;
BusRoute = 0;
StartLoc = 0;
DestLoc = 0;
while (LTrigger >= 1)
{
//Give user a menu and prompt to select input for BusRoute
printf("\n\n\tPlease only use the numbers provided.");
printf("\n\n 1.\n\tRoute_1\tCherokee Park and KFC YUM Center transit.");
printf("\n\n 2.\n\tRoute_2\tUL and Cherokee Park transit.");
printf("\n\n 3.\n\tRoute_3\tUL and KFC YUM Center transit.");
printf("\n\n\n\t Please select one route from the above menu.");
printf(" \n\n\tOnly use the single digit corresponding to the route: ");
scanf("%d" , &BusRoute);
//Refresh window
system("cls");
if(isdigit(BusRoute))
{
//Use switch to determin user's Route. Then present choice of To/From
switch (BusRoute)
{
case 1:
printf("\n\n\tYou have chosen Cherokee Park and KFC YUM Center transit.");
printf("\n\n\tIf you want to travel from Cherokee Park to KFC YUM Center enter C.");
printf("\n\n\tIf you want to travel from KFC YUM Center to Cherokee Park enter K.");
printf("\n\n\tEnter your seletion now: ");
scanf("%c" , &StartLoc);
break;
//give two if statements to determine users location and confirm destination
if (StartLoc == 'c' || StartLoc == 'C')
{
printf("\n\n\tYou have chosen to travel from Cherokee Park to KFC YUM Center.");
printf("\n\n\tTo confirm you want to travel from Cherokee Park to KFC YUM Center please enter K: ");
scanf("%c" , DestLoc);
//refresh
system("cls");
//confirmation of destination
if (DestLoc == 'k' || DestLoc == 'K')
{
printf("\n\n\tYour bus route will pick you up from Cherokee Park and take you to KFC YUM Center.");
getch();
}//end dest
}//end start
//false user input
else
{
printf("\n\n\tYou did not enter a correct character.\n\n\tPress enter and only enter specific values.");
getch();
//reset loop and refresh
LTrigger = 1;
system("cls");
}//end else
case 2:
printf("\n\n\tYou have chosen Cherokee Park and UL transit.");
break;
case 3:
printf("\n\n\tYou have chosen UL and KFC YUM Center transit.");
break;
}//end switch
}//end if
else
{
printf("\n\n\tYou did not enter a number.\n\n\tPress enter and only enter specific values.");
getch();
//reset loop and refresh
LTrigger = 1;
system("cls");
}//end else
}//end loop
getch();
}//end main

isdigit takes a character and says if it is a character between '0' and '9'. But you are passing it an integer, not a character, so its output is meaningless.
If you want to know if the scanf succeeded, just check its return value: it will be 1 if it worked, or 0 if it failed (actually it will return the number of variables assigned):
if (scanf("%d", &BusRoute) > 0)
{
If you want to know if BusRoute is one digit long, then you can simply check it to be between 0 and 9 (or 3), but there is no need to do that: instead, add a default: clause to your switch.
BTW, you have missed a & in the line
scanf("%c" , DestLoc);
It should be:
scanf("%c" , &DestLoc);
Also, it is usually a good idea to add a space before the %c it will eat out any space or carriage return left in the buffer (from the previous user operation, for instance):
scanf(" %c" , &DestLoc);
Ditto, for the StartLoc case.

It's tricky to answer this without seeing your code. You can turn a character into an integer with a typecast:
switch((int) variable)
If variable is a character entered by the user, the typecast (int) will convert it to its ASCII code for the switch. Usually, though, C doesn't require typecasts to interpret characters as integers.

Look At this:
char charBusRoute;
int BusRoute;
/* ... */
scanf("%c",&charBusRoute);
if(isdigit(charBusRoute)){
BusRoute = charBusRoute - '0';
/* ... */
}

Related

When trying to output an integer, to a file it outputs an array of numbers

I'm writing a function that will give the user an option to choose an item from a list.
When an option is chosen it should then call a dedicated function to ask for the quantity of the item and then output it to a file. Below are the two functions.
void pos2()
{
int choice;
printf("\n Enter The item : ");
scanf("%d", &choice);
switch (choice) {
case 1:
apple();
break;
case 2:
editInventory();
break;
case 3:
printf("\n Returning... \n\n");
printf("Returning in 3 seconds...\n");
Sleep(3000);
system("cls");
printMenu();
default:
system("cls");
printf("\ninvalid choice Try again \n");
printMenu();
}
}
void apple()
{
FILE*out=fopen("pos.txt","w");
int amt;
printf("Apple Choosen\n");
printf("Enter the Amount\n");
scanf("%d",&amt);
fprintf(out,"%d",&amt);
}
In this case, the user is only able to choose 1 at the moment which will ask them to enter the number of apples, and then enter, it would save the value to a text file called pos.txt. When I do enter an amount it appears I'm given the address value or some sort of array in return. This is the output in the text file:
6421716
if anyone can offer assistance or guide me in the right direction that would be appreciated. Thanks in Advance
Great News, #Passerby (https://stackoverflow.com/users/17196203/passerby) commented the solution under my Question.
The issue here was the & in my fprintf(out,"%d",&amt); which was causing the weird number to be outputted. Thanks once again to everyone helping me solve this and a special thanks to #Passerby for the solution.

Nested if statement in C - why doesn't it evaluate the last else if?

The following code does not execute the last else if statement when you assign to choice value 3.
#include<stdio.h>
#include<stdlib.h>
int main() {
puts("Specify with a number what is that you want to do.");
puts("1. Restore wallet from seed.");
puts("2. Generate a view only wallet.");
puts("3. Get guidance on the usage from within monero-wallet-cli.");
unsigned char choice;
choice = getchar();
if ( choice == '1' ) {
system("nice -19 ~/monero-x86_64-linux-gnu-v0.17.2.0/monero-wallet-cli --testnet --restore-deterministic-wallet");
exit(0);
}
else if ( choice == '2' ) {
system("nice -19 ~/monero-x86_64-linux-gnu-v0.17.2.0/monero-wallet-cli --testnet --generate-from-view-key wallet-view-only");
exit(0);
}
else if ( choice == '3' ) {
puts("Specify with a number what is that you want to do.");
puts("1. Get guidance in my addresses and UTXOs");
puts("2. Pay");
puts("3. Get guidance on mining.");
unsigned char choicetwo = getchar();
if ( choicetwo == '1' ) {
printf("Use \033address all\033 to get all your addresses that have any balance, or that you have generated at this session.");
printf("Use \033balance\033 to get your balance");
printf("Use \033show_transfers\033 to get ");
printf("Use \033show_transfers\033 out to get ");
printf("Use \033show_transfers in\033 to get your balance");
}
}
return 0;
}
I get the following output When I enter 3:
Specify with a number what is that you want to do.
1. Restore wallet from seed.
2. Generate a view only wallet.
3. Get guidance on the usage from within monero-wallet-cli.
3
Specify with a number what is that you want to do.
1. Get guidance in my addresses and UTXOs
2. Pay
3. Get guidance on mining.
I'm really blocked, something is missing and I have no clue why it does not proceed to take the input from the user for the second time.
When you enter "3" for the first input, you're actually inputting two characters: the character '3' and a newline. The first getchar function reads "3" from the input stream, and the second one reads the newline.
After accepting the first input, you'll want to call getchar in a loop until you read a newline to clear the input buffer.
choice = getchar();
while (getchar() != '\n');

Main Menu choice prompt is gathered even on sub Function scanf (C)

Im creating a program that has a Main Menu linked to a couple of other functions. This is the Main Menu Code
int main(){
int iMenuChoice,exit;
iMenuChoice=0;
exit =1;
while (exit !=0){
system("cls");
printf("**********Main Menu************\n");
printf("*1) Cartesian Plane *\n");
printf("*2) Number to Words *\n");
printf("*3) b *\n");
printf("*4) c *\n");
printf("*5) d *\n");
printf("*6) e *\n");
printf("*7) Exit *\n");
printf("*******************************\n");
scanf("%d",&iMenuChoice);
switch (iMenuChoice) {
case 1:
Cartisian();
break;
case 2:
Num2Word();
break;
case 3:
break;
case 4:
break;
case 5:
break;
case 6:
break;
case 7:
system("cls");
printf("\n\nThank you for using our Program\n\n ");
exit = 0;
break;
default:
break;
}
}
getche();
}
So I test my Number to words function which prompts for a User input (Int).
But when I enter the number, The function will ask for another number (no printf prompt just a _ that waits for a number input), Lets call this mystery number X.
After the function is done converting the number, The Program will go to main menu for a split second and automatically goes to another function.
I realized that The mystery number X is somehow being used as an advance menu input! I dont know what i did wrong.
Here is the code for The num2Word function.
int Num2Word()
{
int iWor,iOnes,iTens,iHundred,iThousand;
system("cls");
printf("Enter a number(max 3000)\n");
scanf("%i \n",&iWor);
if(iWor<=3001)
{
iOnes=iWor%10;
iWor=iWor/10;
iTens=iWor%10;
iWor=iWor/10;
iHundred=iWor%10;
iWor=iWor/10;
iThousand=iWor%10;
Thousand(iThousand);
Hundred(iHundred);
if(iTens!=1)
{
Tenty(iTens);
Ones(iOnes);
}
if(iTens==1)
Exception(iOnes);
}
else{
printf("beyond 3000");
}
getche();
return 0;
}
The Tenty,Ones, Hundredth and Thousandths all use Switch, same structure as code below:
int Ones(int x)
{
if(x!=0){
switch(x)
{
case 1:
printf("One");
break;
case 2:
printf("Two");
break;
case 3:
printf("Three");
break;
case 4:
printf("Four ");
break;
case 5:
printf("Five");
break;
case 6:
printf("Six");
break;
case 7:
printf("Seven");
break;
case 8:
printf("Eight");
break;
case 9:
printf("Nine");
break;
default:
break;
}
}
return;
}
Since I cant post images yet ill try to show how the function output looks like
Enter a Number (Max 3000):
619
//I press enter here and nothing happens
3 //I must input another number for it to show the conversion, in this case number 3.
six hundred nineteen
After this, itll go back to main menu for a split sec and go straight to Main() Switch(iMenuChoice) Case 3.
There's no mystery number X or ghost :)
Change
scanf("%i \n",&iWor);
to
scanf("%i",&iWor);
The whitespace characters you have in the format string of scanf, ignores all whitespace characters. That's why you are forced to input a non-whitespace character.
I realized that The mystery number X is somehow being used as an
advance menu input! I dont know what i did wrong.
There is no mystery number X. The problem in your code is this line:
scanf("%i \n",&iWor);
This scanf ignores white-space characters. When a white-space character is specified as directive in scanf. This directive maches any amount of white space, including none, in the input. That's why you have to insert the second "mysterious" value. According to scanf documentation a white space character is a sequence of white-space characters (space, tab, newline etc.; see isspace(3)).
To solve the issue, you can just %i directive. For example:
scanf("%i",&iWor);
Docs: http://man7.org/linux/man-pages/man3/scanf.3.html

program running through my if else after function call

I have a class assignment in C to make a simple calculator that performs three calculations. I haven't completed all of the functions yet but I am having a problem with my calcMenu function. When the function is called the program runs through all of the if else statements and unknown to me, performs only the else statement which is error checking. Than the function is run again which is intended but this time it does not run through all of the if else statements and allows the user to make a choice. I know I have done something really stupid but have been racking my brain for the last hour. If anyone has any pitty for me, than please point me in the right direction. I know all the system calls will Irk some but this is a basic class and our instructor has told us to use them.
Thanks in advance,
Mike
#include <stdlib.h>
#include <stdio.h>
#include <ctype.h>
#define pause system ("pause")
#define cls system ("cls")
//Prototype calculate functions here
void evenOrOdd(int userNumber);
void squareNum(int userNumber);
void cubeNum(int userNumber);
void calcMenu(int userNumber);
void main() {
//Declare local variables here
int userNumber = 0;
printf("\t\t\tThe amazing three function caluculator\n\n\n");
printf("Please enter a whole number that you would like to calculate\n");
scanf("%d", &userNumber);
calcMenu(userNumber);
}
void calcMenu(int userNumber)
{
char calculateOption;
printf("\nWhat calculation would you like to perform with your number?\n\n");
printf("Press A.) to check if your number is even or odd.\n\n");
printf("Press B.) to calculate the square of your number.\n\n");
printf("Press C.) to calculate the cube of your number.\n\n");
printf("press D.) to exit the program.\n");
scanf("%c", &calculateOption);
calculateOption = toupper (calculateOption);
if (calculateOption == 'A')
{
evenOrOdd(userNumber);
}
else if (calculateOption == 'B')
{
squareNum(userNumber);
}
else if (calculateOption == 'C')
{
cubeNum(userNumber);
}
else if (calculateOption == 'D')
{
system("cls");
printf("Thank You for using my amazing calculator.\n\n");
system ("pause");
system ("exit");
}
else
{
printf("Please enter a valid choice");
calcMenu(userNumber);
}
}
void evenOrOdd(int userNumber) {
userNumber = userNumber %2;
if (userNumber == 0)
{
printf("Your number is even. \n");
}
else
{
printf("Your number is odd. \n");
}
}
void squareNum(int userNumber) {
}
void cubeNum(int userNumber){
}
When you read input with scanf you have to press the Enter key to make the program continue. Your scanf call reads the single character from the input, but leaves the Enter key still in the input buffer, to be read next time you call scanf.
There is a very simple trick to solve that: Place a space in the scanf format string before or after the "%c". This will make scanf skip whitespace.
scanf("%c ", &calculateOption);
If you stepped through the code with a debugger you would have easily seen that calculateOption would have been the newline character.
First of all, You can condense all those printf statements into one function to save the extra calls.
Next, you should probably indent your functions, I can't tell where one begins and another ends at a glance.
Third, don't use system("pause"), use getchar().
Fourth, this is optional, you might want to turn those if statements into a switch statement.
Now, on to your question. First of all, instead of using scanf("%c", &calculateOption), just use getchar() here too. In this case, I would write calcMenu() as this:
int calcMenu(int userNumber){
printf("\nWhat calculation would you like to perform with your number?\n\n\
Press A.) to check if your number is even or odd.\n\n\
Press B.) to calculate the square of your number.\n\n\
Press C.) to calculate the cube of your number.\n\n\
Press D.) to exit the program.\n");
switch(toupper(getchar())){
case 'A':
evenOrOdd(userNumber);
break;
case 'B':
squareNum(userNumber);
break;
case 'C':
cubeNum(userNumber);
break;
case 'D':
system("cls"); //this is bad, really.
printf("Thank You for using my amazing calculator.\n\n");
getchar();
return 0;
default:
printf("Please enter a valid choice: ");
calcMenu(userNumber);
break;
}
}
Also, main should always return a value. void main is bad practice.
Disclaimer: The code isn't tested, you shouldn't copy/paste it anyways. I also don't know if you're being forced to use some things or not...

Switch and default: for C

Sorry if this sounds like a very basic question, it is my first time on here!
I am having some difficulties with coding for C, specifically with a switch and the default of that switch. Here is some example code:
#include<stdio.h>
int key;
main()
{
while((key=getchar())!=EOF)
{
printf("you pressed %c \n",key);
switch(key){
case'0':
case'1':
case'2':
case'3':
printf("it's a numeral\n");
break;
default:
printf("it's not a numeral\n");
}
}
}
The actual code is a bunch longer, this is purely an example.
So the code compiles it and I execute it, but I get:
"You pressed 1, it's a numeral, you pressed , it's not a numeral."
My code seems to 'fall through' and repeat itself without referring to either one. If anyone could help that would be great as this is an example in a text book and I am utterly stuck!
Kindest Regards.
You need to account for entering the Enter key, which produces a '\n' on *nix systems. I am not sure what pressing the Enter key does on Windows systems.
Here's your original code doctored up to eat the return key.
#include<stdio.h>
int key = 0;
main()
{
while((key=getchar())!=EOF)
{
if('\n' == key)
{
/* Be silent on linefeeds */
continue;
}
printf("you pressed %c \n",key);
switch(key){
case'0':
case'1':
case'2':
case'3':
printf("it's a numeral\n");
break;
default:
printf("it's not a numeral\n");
}
}
}
You maybe using getchar() for a specific reason, but my experiences in C usually involved reading the whole line, and RTL functions like scanf will eat the line terminator for you.
You need to eat the newline character, that is put in the read buffer when you hit return.
Issue another call to getchar after or before the switch to solve your problem.
Here is an idea...immediately before the printf(), insert logic to ignore spaces and all control characters...
if(key <= ' ')
continue;
printf(...) ...
I dont know if that is the problem, but you have three case without a break. So you press key "1" and there is nothing to do for the programm and so ins go to the next case how is right and this is the default.
Although you take a char in an int-variable???
In your Example it is a better way to take a if-clause like this:
#include<stdio.h>
char key;
main()
{
while((key=getchar())!=EOF)
{
printf("you pressed %c \n",key);
if(key == '0' || key == '1' || key == '2' || key == '3'){
printf("it's a numeral\n");
}
else {
printf("it's not a numeral\n");
}
}
Code is not tested. ;-)
The best way in bigger programms is to work with regular expressions.
I hope, this answer was helpful.
the problem might be due to, input buffer not flushing. when "1" is matched in the switch case, a newline character remains in the buffer.
try this,
fflush(stdin)

Resources