Need help with basic program in C - c

I have a menu when i select 2 variables and then i must choose between a man and a woman. After that i must go to man.c or woman.c with the 2 variables previously choosed but i dont know how can i do that.
my main.c (only when the man option in the menu):
printf("Insert weight: ");
scanf("%f",&a);
printf("Insert high: ");
scanf("%f",&b);
switch(opcion){
case 'm':;
--here i want to go to man.c to continue with other menu but knowing variables weight and high--
man.c and woman.c are similars the ionly difference is when calculates the body mass index
man.c :
int bmi(float weight, float high){
float bmi;
char opcion;
printf("a) Calculate body mass index");
switch(opcion){
case 'a': bmi = weight / high;
break;
}
}
now i ave only this and woman is the same. When is finished man.c and woman.c will have 4 options using weigh, high and some variables more that they asked when needed with scanf.

I'd suggest you call a function (say manMenu()) and keep it in same .c file.

1) You can't simply navigate through c files in C.
2) You can do that using includes & classes, but it's a bit hard for a beginner
3) The right way to do it is something like this:
printf("M/F");
scanf("%f",&option);
switch(option){
case M:
do_man();
break;
case F:
do_woman();
break;
}
And you should declare the functions do_man() and do_woman() before the main.

General:
It's mistake about thinking about code in means of filenames. Instead you should think about functions.
add error handling to the menu e.g. verify input and repeat in a loop until correct input or escape char.
Solution.
Add two functions void handleMan(float weight ,float height); and void handleWoman(float weight ,float height); prototypes to main.c (just copy code before menu() or main() and implement them in man.c and woman.c later on call right method upon user selection.

The easiest way would be to call a gender specific function in the switch. For example man_menu() and woman_menu().
These could also be located in different .c files but then you need to link the object files together.

Well you have to define procedures for man and woman and call procedure in switch statement and perform your individual activities in the respective methods .

Related

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

Re-execute program based on user input in 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.

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.

error LNK2019: unresolved external symbol, fatal error LNK1120: 1 unresolved externals

I have looked both of these errors up on this website and tried to change my code to accommodate the changes that were suggested but they did not work for my code, so here is my code and I hope you guys can help me out. It is not complete as I am only about half way done with the assignment but I cannot see what I have done so far because it won't build correctly. Thank you!
#include <stdio.h>
//int CheckMoney(double *payment, double item_cost); //compares the amount the user has deposited to the price of item selected. It returns 1 if the amount is at least enough to cover the cost, 0 if there is not enough.
//void GetMoney(double *payment, double item_cost, char selection); //calls CoinMenu function to collect money from the user and CheckMoney function to keep comparing the deposited amount to the item cost.
//void GetChange(double *payment, double item_cost, double *change); //calculates the amount of change to be returned
void CoinMenu(double *payment);
void Quit(char *again);
void GetCost(char selection, double *item_cost);
void Menu(char *selection);
// Displays the list of snack items and prompts for the user’s choice
void Menu(char *selection)
{
printf("Welcome to the AAA vending machine, where your wishes could come true for less than $2");
printf("/nWhich one of our delicious snacks would you like to sink your teeth into?");
printf("/nP – Potato Chips $1.25");
printf("/nS - Snickers Bar $1.35");
printf("/nT – Pop Tart $0.95");
printf("/nC – Cookies $1.50");
printf("/nB – Brownie $1.75");
printf("/nN – Nuts $1.40");
printf("Enter your delicious selection here: ",*selection);
scanf(" %c", &*selection);
//determine cost of selection
GetCost(*selection, 0);
}
//sets the cost of the purchase based on value in selection
void GetCost(char selection, double *item_cost)
{
if(selection=='P'||'p')
{
*item_cost=1.25;
}
else if(selection=='S'||'s')
{
*item_cost=1.35;
}
else if(selection=='T'||'t')
{
*item_cost=0.95;
}
else if(selection=='C'||'c')
{
*item_cost=1.50;
}
else if(selection=='B'||'b')
{
*item_cost=1.75;
}
else if(selection=='N'||'n')
{
*item_cost=1.40;
}
else
{
printf("That is not a valid selection, have a nice day!");
return;
}
}
//displays menu of coins and gets user input of the coins deposited
void CoinMenu(double *payment)
{
printf("Please deposit your money by the following numbers:");
printf("/n1 - $5.00");
printf("/n2 - $2.00");
printf("/n3 - $1.00");
printf("/n4 - $0.25");
printf("/n5 - $0.10");
printf("/n6 - $0.05");
printf("/n7 - $0.01");
printf("/nAmount deposited: ");
scanf(" %c", &*payment);
}
void Quit(char *again)
{
printf("Would you like to buy another snack?");
printf("/nEnter Y for yes or N for no: ", *again);
if(*again=='N'||'n')
{
return;
}
else if(*again=='Y'||'y')
{
void Menu(char *selection);
}
}
For the error mentioned in your question - you have no main() function, and you don't have a complete C program until you write one. Your linker is looking for it, and giving you an error when it can't find it.
There's plenty of other errors here, too, including:
printf("/n1 - $5.00"); - it's \n, not /n, and it's not clear why you're putting the newline at the beginning of the line, instead of the end: printf("/nN – Nuts $1.40"); printf("Enter your delicious selection here: ",*selection); is going to give you some weird looking text, for instance.
Talking of which, printf("Enter your delicious selection here: ",*selection); - you provide a char as an argument to printf(), but according to your format string, it's not expecting any arguments. Should be printf("Enter your delicious selection here: "); Since you're not terminating it with a newline, you should also add an fflush(stdout); before your call to scanf().
scanf(" %c", &*selection); - why dereference a pointer only to take its address again? There are some good reasons not to, including the fact that it amounts to taking the address of a temporary value which is illegal. You already have a pointer, so use it - should be scanf(" %c", selection);
if(selection=='P'||'p') - binary logical operators don't work like that in C, should be if ( selection == 'P' || selection == 'p' ).
scanf(" %c", &*payment); - same issue with as point 3 above, plus here payment is a double *, and you're telling scanf() to read a char. Should be scanf("%lf", payment);
void Menu(char *selection); at the bottom - as pointed out in the comments to your main question, this is a function declaration, not a function call, and effectively does nothing here. Should be Menu(again), although really it should just return true or false, and the caller should decide whether or not to call Menu() again.
Several of these errors are repeated in various places throughout your code, I haven't listed every single example. This passing around of pointers is just really weird design, too. All of your functions are declared as returning void - if you changed them to return a value and employed some local variables, instead, you'd be able to avoid passing any pointers at all.

Can Ruby call methods or procs like c calls functions?

I am pretty new to Ruby. I am college and just did a programming course that covered regular c. My final project for class was a slop intercept project, which was fairly easy, but i had to use functions for everything, for example:
#include <stdio.h>
#include <math.h>
int get_problem(int *choice){
do {
printf("Select the form that you would like to convert to slope-intercept form: \n");
printf("1) Two-Point form (you know two points on the line)\n");
printf("2) Point-slope form (you know the line's slope and one point)\n");
scanf("%d", &*choice);
if (*choice < 1 || *choice > 2){
printf("Incorrect choice\n");}
}while (*choice != 1 && *choice !=2);
return(*choice);
}
...
int main(void);
{
char cont;
do {
int choice;
double x1, x2, y1, y2;
double slope, intercept;
get_problem (&choice);
...
I have several more functions completing the entire program. I got a new job and i need to start learning Ruby, So for my first project I wanted to convert this program into Ruby, now I was able simply get rid of the functions and just run it without methods or procs. I wanted to know if it is possible to do the same thing, define a method, then call the method without giving an input, but getting back the variables stored in the method. Would it be possible using methods or procs. Here is a little of what i have so far using a proc.
get_problem = Proc.new {
begin
puts "Select the form that you would like to convert to slope-intercept form: "
puts "1) Two-Point form (you know two points on the line)"
puts "2) Point-slope form (you know the lines slope and one point)"
choice = gets.chomp.to_i
if (choice < 1 || choice > 2)
puts "Incorrect choice"
end
end while (choice != 1 && choice !=2)
}
....
begin
get_problem.call
case choice
when 1
get2_pt.call
display2_pt.call
slope_intcpt_from2_pt.call
when 2
get_pt_slope.call
display_pt_slope.call
intcpt_from_pt_slope.call
Now I know I probably have it all wrong, but I figured I would give it a shot. I have it as methods before where I had
def get_problem(choice)
....
end
....
get_problem(choice)
....
Is there something basic I am missing? As you can see, i used pointers in c and had to initialize the variables in the main.
Thank you for taking the time to help me out.
Robert
You can't pass a pointer to a variable in Ruby, but I don't think you need to do that to accomplish what you're trying to do. Try this:
def get_problem
puts "Select the form that you would like to convert to slope-intercept form: "
puts "1) Two-Point form (you know two points on the line)"
puts "2) Point-slope form (you know the lines slope and one point)"
loop do
choice = gets.chomp.to_i
return choice if [1, 2].include? choice
STDERR.puts "Incorrect choice: choose either 1 or 2"
end
end
choice = get_problem
puts "The user chose #{choice}"
This defines a method get_problem which loops until the user chooses either 1 or 2, and returns their chosen number, which you can store in a top-level variable choice.

Resources