Re-execute program based on user input in C - c

Hi i'm trying to learn programming in C on my own and have managed to make a verry, verry simple program that calculates the surface of a circle based on user input.
However the program runs only one time and then closes it.
This was initially the intention because it is only for learning but i want to expand on this program to increase my skills/knowledge and hope someone can point me in the right direction.
What i want to do now is instead of terminating the program after running it once; i would like to offer the user a choise to either stop the program or to continue it and to calculate a new circle.
I understand that it has to be done with an if else statment with the getchar function but i have some issues wrapping my mind around it on how to put it in a program flow. I hope someone can give me some directions on how to tackle this problem or can point me to some documentation that explains this properly.
Currently i have this:
int main(void){
float diameter;
double straal;
double oppervlakte;
char ch;
printf("Type de diameter van de cirkel:\t");
scanf("%g", &diameter);
printf("\n");
straal = diameter / 2;
oppervlakte = PI * (straal * straal);
printf("De straal =\t%g \n\n", straal );
printf("De oppervlakte =\t%f \n\n" , oppervlakte);
printf("Druk enter om af te sluiten.");
scanf("%c",&ch);
getchar();
return 0;
}
and im trying to accomplish something like this(below) but i can't get it to work properly (i get the warning that the label "diameter" is not defined while trying to compile it.)
#include <stdio.h>
#define PI 3.14
int main(void){
float diameter;
double straal;
double oppervlakte;
char ch;
printf("Type de diameter van de cirkel:\t");
scanf("%g", &diameter);
printf("\n");
straal = diameter / 2;
oppervlakte = PI * (straal * straal);
printf("De straal =\t%g \n\n", straal );
printf("De oppervlakte =\t%f \n\n" , oppervlakte);
printf("Druk 'd' om door te gaan of druk enter om af te sluiten.");
if(getchar() == 'd')
{
goto diameter; /* tried to use main(void) here but that also doesnt work */
}
else{
scanf("%c",&ch);
getchar();
}
return 0;
}
i do understand that goto is not the best practise to use but in this case it seemed the easyest way to solve this issue. (and the program is not that complex ofc). However if im wrong in this please let me also know.

Option 1: (likely the best choice): use a do..while loop. Place a do { above your primary code block, and add a } while (<repeat condition>); at the end. The program will run through the code once, check the repeat condition (which will be "did the user enter yes"), and if so repeat, otherwise not.
Option 2: recursively call main(). You said you "tried that", but I'm not sure if you tried it by attempting to use a goto or not. Just use the line main() to call the function again. Note that if you do this too many times you can end up with a stack overflow, because the computer keeps track of each call. It takes a lot to have it be a problem, but with enough repeats it can happen.

You can do something like:
while(true) //this is an endless loop
{
//display a menu like
1. calc area
2. [anything else if you want to add in future]
.
.
.
0. exit
//take user input (e.g 1 for calculating the area)
switch(user input)
{
case 1:
//code to calculate area
break;
case 2:
//code for anything else
break
case 0:
exit(0); //this will terminate the program
}
}
If you follow this pattern, you can add more options to your program in future. You just need to add a case in your switch statement and include that operation in your menu. You can search for menu driven c program to get more details. Try reading about while loop and switch... case statements.

I actually managed to make work in both ways.
Thanks for the tips and suggestions.

Related

Always running a line/Running 2 lines at once in C

Im hoping to make a clicker game from C. I already have the clicking mechanics down and im pretty confident i can do everything else but I can seem to find any articles or help regarding having a running line in the background. For example I have a line of code that allows whenever I click a key i get +1 money, but like most clicker games I want a auto klicker to be running every second or so. So i can just be normally clicking while at the same time theirs a function or line of code that adds +5 money every so often. Ive made my own (delay) code so thats not an issue, its just running a line in the background. Heres what I have so far...
#include <stdlib.h>
#include <stdio.h>
#include <conio.h>
#include <time.h>
int main()
{
int menu;
char ch;
int klicks;
int klickses;
klicks=0;
void delay(unsigned int mseconds)
{
clock_t goal = mseconds + clock();
while (goal > clock());
}
printf("Welcome to Key Klicker! This game is a idle game where you slowly gain more and more klicks over time.\n The game is never ending but their are milestones to reach.\n A menu will open up to help navigate through the game.\n");
do{
printf(" 1: Clicking\n 2: Shop\n 3: Exit\n\n");
scanf("%d", &menu);
if(menu == 1)
{
klickses=0;
{
char ch;
printf("Klick as fast as you can! (ESC to exit)\n");
while (1) { //define infinite loop for taking keys
if (kbhit) {
ch = getch(); // Get typed character into ch
klicks=klicks+1;
klickses=klickses+1;
if ((int)ch == 27) //when esc button is pressed, then it will comeout from loop
break;
printf("+1\n");
}
}
}
printf("You have a total of %d klicks!\n", klicks);
printf("You earned %d klicks that session!\n\n", klickses);
}
else if(menu == 2)
{
printf("work in progress\n");
}
else if (menu == 3)
{
printf("exit work in progress\n");
}
}while (1);
}
Hey guys I got it to work! Basically instead of having a auto adder every so seconds I decided to make a stopwatch that starts at the beginning and ends when I go out of the auto clicker. I then minus the end time from the start time and just calculate the auto clicks from their!
I also think with a new variable I just learned called time_t I could make an if statement that if a certain time is passed it would add 5 but anyhoo im not going to vere onto another path. This communities super helpful keep it going!

function prototype in c, compile error

So am trying to learn c by-myself (basically not having any previous experience in any programming language) and now I have some issues with prototyping some of my functions to use in header files.
For the sake of learning I only use the < stdio.h > lib and only use the printf and scanf functions and for now it only prints to console.
I was able to code a working prototype function for my menu that only uses the printf function but the scanf gives me more issues and it just refuses to compile and am having trouble to see where my thinking error is.
my main program:
#include "menu.h"
#include "circlefunctions.h"
#include "input.h"
int main(void){
float diameter;
double straal;
double oppervlakte;
double omtrek;
while(1){
menu();
user_input();
system("cls");
switch(user_input())
{
case 1:
printf(" ----------------------------------------\n");
printf(" Typ de diameter van de cirkel: ");
scanf("%g", &diameter);
printf(" ----------------------------------------\n");
straal = diameter / 2;
oppervlakte = PI * (straal * straal);
omtrek = 2 * PI * straal;
printf(" De straal = %f \n\n", straal );
printf(" De oppervlakte = %f \n\n" , oppervlakte);
printf(" De omtrek = %f \n" , omtrek);
printf(" ----------------------------------------\n");
break;
case 2:
return(0);
case 3:
return(0);
case 9:
return(0);
case 0:
return(0);
}
}
return 0;
}
and the stubborn header:
#include <stdio.h>
void user_input();
void user_input(){
scanf("%d", &user_input);
}
The error that I get while trying to compile is in input.h
the part with; scanf("%d", &user_input);
errorcode: format '%d' expects argument type of 'int ', but argument 2 has type 'void () ()'.
And I also got an error on the switch in the main program that the switch quantity is not an integer. I suspect that this error is related but am not sure. I still have to debug that part but if anyone is willing to point me to the right documentation i would much appreciate it.
And a second question that I have is also related to headers: I have < stdio.h > already included in "menu.h". Would I need to include it again in "input.h"?
(if i understand correctly how the preprocessor works i should not have to include it but I can't find anywhere where this is explained in simple terms unfortunately.)
Edit:
Thank you all for providing valuable information.
#zenith Thank you for your example. I hope you don't mind me asking some more.
I have replaced my code with yours in the "input.h" and it will compile and run now. However the behavior has changed. For some unclear reason i now have to input the choice twice before the program accepts my input. So the 1st input gets ignored after an enter and it will only accept the 2nd input.
Could you perhaps point me in the direction what causes this bug? or perhaps point me to some documentation where this is explained? I don't want to take up to much of you valuable time of-course.
Edit 2
Thanks for the reply and info. I got the bug out and it is working as intended(that was silly of me not to see that).
And to the rest who replied: Ill take your information of-course and also learn from that. Thank you all!
user_input() doesn't return anything, since it's declared void.
But you're trying to use the non-existing return value: switch(user_input()).
This causes undefined behavior.
Additionally, this:
scanf("%d", &user_input);
tries to read an int from stdin and store it in the memory address of the user_input function. Not a good idea. Again, undefined behavior.
What you probably want the function to look like:
int user_input(){
int number; // store user input to this variable
scanf("%d", &number);
return number; // return the user input so that it can be used outside the function
}
If you have header files declared in a previous header file. You will not need to include it again in the subsequent included header files. I tend to not include header files in my local *.h files just for that reason. It avoids circular includes if you declare your includes in the .c files as much as possible.
Your scanf function has as its second argument a function of type void(), void(). Meaning it takes no arguments and returns nothing or "void". I think you want your user_input to be a variable of type 'double' that is filled somewhere, maybe via some user input from the console using a call to 'gets' from stdin.
HTH

I need a function that ask the user to enter a pin and after 3 wrong attempts, they program terminates

I have to write an ATM program for a class, and i cant figure out how to make a function that will ask the user for a pin and if the pin is entered incorrectly three times the program will display an exit message then terminate.... this is what i have some far. I think my issue is i don't know the correct syntax to handle my issue.
I know i will need a for loop but not sure how exactly to construct it.
void validate_acc(){
int user_acc_try;
printf("Please enter your account number: ");
scanf("%d", &user_acc_try);
if(user_acc_try != account_number){
printf("You entered the wrong account number");
}
else{
printf("");
}
}
void validate_pin(){
int user_pin_try;
printf("Please enter your pin number: ");
scanf("%d", &user_pin_try);
if(user_pin_try != pin){
printf("You entered the wrong pin number.");
}
else{
printf("");
}
}
void validate(){
validate_acc();
validate_pin();
}
Secondly, since i can only post every 90 minutes might as well ask another question, I do not know how to make a function go back to the beginning of my program like for example say after an deposit, what is the logic i would need to use to have a function go back to the beginning of my main function. I know of goto labels, that didnt seem to work when i put it in front of my main function like so...
MAIN:
int main()
i would put goto main; in another function and i would get a.... Main is not defined error. I have read a few different questions on here about labels but cant find anything that helps, if someone could guide me in the right direction, you would be giving me a great deal of relief.
thank you in advance.
It's a good idea to write out a flow chart for things like this if you can't figure out how to do it in code.
Please do not use labels/goto in C. It's a nasty habit and it's not needed.
You know how to use if statements to make a decision; think about how you would use a while loop to try to make the same decision over and over again until something changes. For instance, in pseudo-code (because I don't want to do your work for you)
user_has_not_entered_correct_pin = true
retries_left = 3
while retries_left > 0 and user_has_not_entered_correct_pin:
get pin
if pin_is_not_correct(pin) retries = retries - 1
else user_has_not_entered_correct_pin = false
end while
I am limited on time right now, so I will just post a quick help. I would suggest start researching loops in C. Since this is for a class, the book you are using should have information in it about for loops and while loops, but if not, a simple Google search can help a lot.
With a quick search on Google, this site seemed like a decent site for basic information on loops:
Loops in C
It has links and examples of using a for loop, a while loop, a do...while loop and nested loops which should help you solve your problem.
Edited to add:
In your post you mentioned that you think the problem is that you don't know the syntax that you need. It is for that reason that I pointed you to a location that can help you with the syntax that you need to solve your problem rather than show you directly how to solve the problem. I hope that this helps you not only with this question, but going forward in your class as well.
Keep a count variable like I have did below and check the number of attempts:
I don't see a need for goto here. The same logic can be used for checking pin also.
int i=0;
while(1)
{
if(i>2)
{
printf("Maximum attempts reached\n");
break;
}
printf("Enter the acc_num\n");
scanf("%d", &user_acc_try);
if(acc_num == saved_acc_num)
{
// Do your stuff
}
i++;
}
Return value from validate_pin() int validate_pin(){... return 0; .... return 1;} and test it in the main() or your validate().
int i=0;
int result=0;
while ( (result==0)&&(i<3) ){
result=validate_pin();
i++;
}
Dont use goto, learn to use loops.

Why my C program unexpectedly terminates when using floor and ceil and rounding functions?

My project is to create a Calculator, which includes some rounding functions like:
Normal rounding, Floor, and ceiling.
They appear in the program like this:
round(x)
ceil(x)
floor(x)
Here's the code of that menu:
else if (user_input == 3){ /*Rounding Operations*/
instructions_Rounding();
scanf("%d",user_input);
while(user_input!=4){
if(user_input==1){ /*For round(x)*/
printf("\nEnter a number to round it: ");
scanf("%lf",&num1);
double rnd;
rnd = num1+0.5;
result = floor(rnd);
printf("\nResult is %f", result);
user_input=4;
else if(user_input==2){ /*For ceil(x)*/
printf("\nEnter a number: ");
scanf("%lf",&num1);
result = ceil(num1);
printf("\nResult is %f", result);
user_input=4;
}
else if(user_input==3){ /*For floor(x)*/
printf("\nEnter a number: ");
scanf("%lf",&num1);
result = floor(num1);
printf("\nResult is %f",result);
user_input=4;
}
}
}
Note: This loop can be ended by setting user_input to 4, but this loop is inside a bigger loop that can be ended by setting it to 5. I don't know how this might help but I thought it might be the cause of something and it might be worth mentioning.
Anyway, the prorgam runs flawlessly except when I choose anything from this menu, it gives me an error like this:
http://oi44.tinypic.com/2gwdssy.jpg
I really don't see anything wrong with my code. It used to work good before but only when I had a problem with the menus, needed a while to figure how to return to the main menu after each operation instead of getting stuck in an infinite loop. But only when I fixed it did this happen. Not sure why.
Can someone tell me if anything is wrong with this code? Is it normal for it to act this way?
Oh, and I tested it on 3 different computers so it's not a problem from my computer.
This line:
scanf("%d",user_input);
Should be:
scanf("%d",&user_input);

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...

Resources