Why is my variable not updating when I use a switch statement? - c

I am a student, and I am trying to make an adventure text game, without using arrays.
This code is a function, called by main (within another switch case statement). The problem is, the day doesn't update. It only updates when the code is included inline in main.
int getArea (int nArea) //area and day
{
int nShisha, nBall, nLolipop, nPepsi ;
int nUser; //test variables
int nPrice; // testing variable for price
int naUser ;
int nDay;
nDay = 2;
printf("Choose your Area\n");
printf("1. Riyadh\n2. Jeddah\n3. Albaik\n4. Tazaj\n");
printf("5. Go back\n");
scanf("%d", &nArea);
//nArea
do{ //This is for the place
switch (nArea)
{
case 1 :
printf("Riyadh\n");
printf("Day %d of 15\n", nDay);
nDay ++;
if (nDay == 16) {
return 0;
}
getPrice (&nShisha , &nBall, &nLolipop, &nPepsi ) ;// add charge soon
break;
case 2 :
printf("Jeddah\n");
printf("Day %d of 15\n", nDay);
nDay ++;
if (nDay == 16) {
return 0;
}
getPrice (&nShisha , &nBall, &nLolipop, &nPepsi ); // add charge soon
break;
case 3:
printf("AlBaik\n");// add charge soon
printf("Day %d of 15\n", nDay);
nDay ++;
if (nDay == 16) {
return 0;
}
getPrice (&nShisha , &nBall, &nLolipop, &nPepsi );;
break;
case 4:
printf("Tazaj\n");// add charge soon
printf("Day %d of 15\n", nDay);
nDay ++;
if (nDay == 16) {
return 0;
}
getPrice (&nShisha , &nBall, &nLolipop, &nPepsi );;
break;
default : printf("You have entered invalid!");
break;
}
// printf("do you want to go to another place?\n"); //test code change later into better alternative
scanf("%d", &nArea);
}while (nArea!=0); //for area while
}
Can you guys please explain why is it not updating?

Per your clarification, you are talking about variable nDay. In the code presented in the question, this variable is local to function getArea(). I am confident that it is successfully updated in the function, but that will have no effect on any like-named variable in main() or elsewhere. Those are different variables with the same name. Since you describe factoring this code out of main into its own function, I am fairly confident that this is the nature of the problem.
If you want the function to modify a variable that is local to the caller, then the caller must pass a pointer to that variable, and the function must update the caller's variable indirectly, via the pointer. For example, you might declare getArea() like this, instead:
int getArea(int area, int *nDay) {
// ...
You would then also need to get rid of the other declaration of nDay inside getArea():
int nDay;
, and all other appearances of nDay inside the function body would need to be replaced with (*nDay).*
For its part, the caller would need to pass the appropriate pointer, something like:
int main(void) {
int area, rval, nDay;
// ...
rval = getArea(area, &nDay);
// ...
}
* Technically, the parentheses are needed only in some cases, but they are harmless in the rest.

The value of a variable in a user-defined function won't be updated in main() function as long as you are not returning it to to the main() function or the variable is a pointer that had been passed from the main function.
In your code, even though the variable nDay has been updated in the function getArea, the variable won't be updated in main() function if you don't return it. you can use
int getArea (int nArea)
{
...
...
return nDay; // Only this value will be passed to the main() function. nothing else updated here will be passed.
}
int main()
{
int x,y,z, nArea, nDay;//some variable that you declared. Assuming nDay is one of them
...
...
nDay=getArea(nArea); //value returned from the function(which is "nDay" from getArea()) will be assigned to nDay
...
}
Also, I don't see any reason for passing nArea to getArea() as you are overwriting/taking new input(value) of nArea inside the function.
Note the nDay from main() and nDay from getArea() are actually different variable even though they have the same name.

Related

How to pass value from one function to another in C?

Here I have two functions and I call Both of them in my MAIN function. The first function gives me a value of "wage" and I want to use the value of "wage" in my 2nd function. But this doesn't work. Also, I will be using my variable in another function later in my code. Is there any way to call my values efficiently?
Here is the main function call:
#include <stdio.h>
#include <string.h>
int main()
{
categoryA();
workingInfo();
}
1st function that has value of "wage" :
void categoryA()
{
printf("\n\nCategory A: Administrative Worker[1]\n\t Data Entry Operator[2]\n\t Data Entry Clerk[3]\n\t Betting Clerk[4]\n");
int position;
float wage;
float overWage;
char positionName[100];
printf("Choose Your Job Title : ");
scanf("%d",&position);
if(position == 1)
{
wage = 12.5;
overWage= wage*1.15;
strcpy(positionName, "Administrative Worker");
}
else if (position == 2)
{
wage = 13;
overWage= wage*1.15;
strcpy(positionName,"Data Entry Operator");
}
else if (position == 3)
{
wage = 13.2;
overWage= wage*1.15;
strcpy(positionName, "Data Entry Clerk");
}
else
{
wage = 13.5;
overWage= wage*1.15;
strcpy(positionName,"Betting Clerk");
}
printf("wage in the category function : %.2f\n",wage);
}
2nd function where I want to use "wage" :
void workingInfo(float wage)
{
printf("wage in the working info %.2f\n",wage);
}
Change the function so that it returns a float, i.e.
float categoryA()
{
... your current code ...
return wage; // Return the value of wage
}
and use it like:
int main()
{
float f = categoryA(); // Save the returned value (i.e. wage) in
// a variable with the name f
workingInfo(f); // Use f
....
someOtherFunc(f); // Use f again
}
or the more compact version:
int main()
{
workingInfo(categoryA()); // The returned value isn't saved in
// a variable but passed directly to
// the workingInfo function
}
Once categoryA() has returned, its wage variable is gone, as well as out of scope. There's no way it can be accessed.
Rather, I suggest you return wage; at the end of categoryA(), then pass the result in to workingInfo().
You'll need to change the signature of categoryA():
float categoryA()
And change the call to something like:
float wage = categoryA();
workingInfo(wage);
... or...
workingInfo(categoryA());
The simplest way you can do it by making wage as global variable, then also you will be able to use it with in multiple functions too and you can also use it as pointer too if you are comfortable with pointers.

switch cases and one global variable for each case

I am dealing with a issue with switch cases.
Explanation of the program:
main(argc,argv).
argv leads to cases in a switch statement. Depending on the input, the according case will be entered and the corresponding function will be executed. -> Output is always a struct, with different content. More than one input (i.e. main.c case1 case3) is allowed-> executed both cases.
my problem is dealing with the passing of these data's and save it in a global variable, in order to print the collection. Inside of a case, I am passing the local results to the global variable, but after the break statement of the case, the global starts with NULL again and doesn't contain the info's of the executed case.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "m.h"
output* print;
int main(int argc, char* argv[])
{
output_g* global; // global_struct
if(argc > 1)
{
global= create_global(argc-1); // allocation for global struct
for(int j = 0; j < argc; j++)
{
switch (atoi(argv[i]))
{
case 123:
{
output* print= 123();
if(print== NULL)
{
return 0;
}
global = fill_global(global ,print); // hands over the current struct to the global struct
delete(print); // free function
}
break;
case 456:
{
output* print= 456();
if(print== NULL)
{
return 0;
}
global = fill_global(global ,print); // hands over the current struct to the global struct
delete(print); // free function
}
break;
case 789:
{
lfnr++;
output_1* print_liste = 789();
if(print== NULL)
{
return 0;
}
global = fill_global(global ,print); // hands over the current struct to the global struct
delete(print); // free function
}
break;
default:
break;
}
print_global_struct(file,globale_liste);
delete_global(globale_liste);
}//End for-Schleife
}// End If
return 0;
}
a) If I understood you correctly, you don't understand the switch statement :)
A switch statement is similar to nested if statements.
so..
int x = 10;
switch (x)
case 1:
//does not happen, x is not 1
case 10:
//happens ...
after all that x is still 10, unless you changed it in the case statements explicitly. The cases just check to see IF x is a value, it does not SET a value. The same is true for any other variable in your code, the above code would not modify y either, unless you explicitly assign it inside a case it won't change.
b) it is best if you DO NOT declare locals in a case statement. They can become very wonky. The standard c++ rules work: variables declared inside {} pairs are scoped to inside that {} pair, so proper use of them will properly give the correct scope for each case. So it will work as expected if you apply braces. You should NOT declare a local in one case and use it in another, even if you can get it working (you can) it is error prone in that editing the code later can break things, the code can be confusing to read and work with, and its just generally a bad idea.
an example:
int main()
{
int x = 3;
switch(x)
{
case 1: int y;
case 2: y = 3;
case 3: y = 5;
cout << y << endl;
};
}
that compiled and ran for me, printing 5.
It worked fine -- I did not expect that, using g++ c17 options.
I still think it is a bad thing to do as far as reading and following the intent.
if you put {} around the int y statement, it does NOT compile anymore.
If you put breaks after the case 1 and case 2, it does NOT compile anymore.
so it is 'fragile' to being edited, at the very least, to do this.
c) run time won't lose anything. Ive had programs that ran for months on end. Being in a case has no effect on this either. The risk of losing variables is the 'ram' risk that all programs face... if a long running program is killed by power outage or malfunction etc you lose anything not saved to a file and have to start over. Long running programs should save their state periodically to protect against this.

Using a for-loop in C to test the return value of a function

I'm pretty new to coding and especially to C, so I decided to take the CS50 course as an introduction to the language. I just finished watching the first lecture on C and, as a means to test my knowledge on the subject, I attempted to write a short little program. Also I am using the course's library for the get_int() function.
The goal is to test the user's input and check if it's less or equal to ten. If it matches the parameters, the program should print the "Success!" message and exit; otherwise, it should ask for input again. If the input value is over 10, the program responds just as expected, but if you input a value of 10 or less, it ends up asking you for input one more time before actually exiting. I think it's probably something with the "for" loop, but I just can't figure it out.
My code:
#include <stdio.h>
#include <cs50.h>
#include <stdlib.h>
int check_for_value();
int main()
{
for(check_for_value(); check_for_value() != 1; check_for_value())
{
printf("Failed!\n");
}
exit(0);
}
int check_for_value()
{
int i = get_int("Your value: \n");
if(i <= 10)
{
printf("Success!\n");
return 1;
}
else
{
printf("Try again!\n");
return 0;
}
}
That isn't doing exactly what you think it is. In your for loop, each time you write check_for_value(), it is going to call that function. So it will call it the first time and the return value will not matter. It will call it again for the middle statement and then the value will matter because you are comparing the output to not equal to 1. And then again it will call the function in the third statement, where again it won't matter. Usually for something like this, you would use a while loop instead. An example below:
int ret = check_for_value();
while(ret != 1) {
printf("Failed\n");
ret = check_for_value();
}
printf("Success\n");
Technically a for loop can work too as the following:
for(int ret = check_for_value(); ret != 1; ret = check_for_value()) {
printf("Failed\n");
}
The for loop can look very simply
for ( ; !check_for_value(); )
{
printf("Failed!\n");
}
In such a case it is better to use the while loop
while ( !check_for_value() )
{
printf("Failed!\n");
}
As for your for loop
for(check_for_value(); check_for_value() != 1; check_for_value())
^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^
then the underlined calls of the function are not tested.
Also bear in mind that such a definition of a for loop
for(int ret = check_for_value(); ret != 1; ret = check_for_value()) {
printf("Failed\n");
}
is a very bad style of programming. There is redundant records of the function calls. The intermediate variable ret is not used in the body of the loop. So its declaration is also redundant. Never use such a style of programming.
Pay attention to that according to the C Standard the function main without parameters shall be declared like
int main( void )
and the statement
exit( 0 );
is redundant.

Assignment to write a program that gives the user a choice between two options - C

I have an assignment due and I am drawing a blank on what exactly to do... I'm sure it is simple but I havent quite gotten the hang of things yet. The assignment is -
Write a program that gives the user 2 menu options: either call a function that will print a greeting and your name 4 times or call a function that will count down from 10 to 0 and then print "Blastoff!". Both functions should use for loops to print the appropriate output.
I have the prompt and the functions done so far... but I am unsure of how to display one or the other depending on the choice the user makes. Thank you for your help.
#include <stdio.h>
int main (void){
// declare counter variable
int i;
// prompt the user to make a choice
printf("What would you like to do?\n 1. Print my name\n 2. Count down from 10\n");
printf("\n");
// display greeting and name 4 times
for(i=1;i<=4;i++)
{
printf("Hi, my name is Bridget\n");
}
// display countdown
for(i=10;i>=0;--i)
{
printf("%d\n", i);
}
printf("Blastoff!");
}
You should read the input from user's keyboard:
int c;
c = getchar();
if (c == '1')
{
// display greeting and name 4 times
for(i=1;i<=4;i++)
{
printf("Hi, my name is Bridget\n");
}
}
if (c == '2')
{
// display countdown
for(i=10;i>=0;--i)
{
printf("%d\n", i);
}
}
printf("Blastoff!");
you should use Switch case.
switch(choice) {
case 1: //first for loop
break;
case 2: //second for loop
break;
}
Looks like you are missing a couple of points here. Firstly, you have not yet written any functions. Try looking here to gain some insight on that front.
Secondly, to make a choice based on user input you need to actually get that input somehow. You'll probably want to use scanf.
Lastly, once you have the user's input (say, in a variable declared as int input;) you can use if to control the flow of your program based on that variable like this:
if(input == 1){
greet();
}
else {
countDown();
}
Cheers! If you have any further questions feel free to comment below.
First of all you haven't actually declared you functions. Functions in C should be declared like the main function is. For more info in this see here.
// display greeting and name 4 times
void greeting(){
for(i=1;i<=4;i++)
{
printf("Hi, my name is Bridget\n");
}
}
void countdown() {
// display countdown
for(i=10;i>=0;--i)
{
printf("%d\n", i);
}
printf("Blastoff!");
}
To get the user's input the most common way is by keyboard. scanf accomplishes that in C. Details on scanf here
int main(void){
int i, choice;
//prompt the user to make a choice
// You don't need 2 printf for the newlines stick them to one.
printf("What would you like to do?\n 1. Print my name\n 2. Count down from 10\n\n");
//This takes the user's input and puts it in the variable choice
scanf(%d, &choice);
}
Lastly to decide what to do based on the user input you can use either an if then else statement or a switch. I will provide a solution with an if statement and you can figure the one with the switch on your own. Your final code should look like this.
int main(void){
int i, choice;
//prompt the user to make a choice
// You don't need 2 printf for the newlines stick them to one.
printf("What would you like to do?\n 1. Print my name\n 2. Count down from 10\n\n");
//This takes the user's input and puts it in the variable choice
scanf(%d, &choice);
if(choice == 1){
greeting();
}else{
countdown();
}
}
// display greeting and name 4 times
void greeting(){
for(i=1;i<=4;i++)
{
printf("Hi, my name is Bridget\n");
}
}
void countdown() {
// display countdown
for(i=10;i>=0;--i)
{
printf("%d\n", i);
}
printf("Blastoff!");
}
Bear in mind that this code has a lot of flaws (error checking mainly) but I guess your assigment is not about that.
First of all you need to include libraries with function you will need. You do this by
#include <someLibrary.h>
at the beggining of you document. Libraries mostly have .h extension. Always look for them if you try to do something. You consider them to have best performance and functionality as possible (not always true).
What is next you declare your functions. Function has name, arguments which are going into it, body in which they do something and return value (can be float, int, char etc). If function doesnt return anything, they return void (dont have return at the end). You declare functions before main() with only types of arguments. Whole body is after main (it is better looking).
If you declared function with arguments, you have to provide these arguments to function in () brackets. Even if no arguments are needed, you use them like getch() in example below. Note that function become what it return. If you declared some new variables in function they will be visible only in function. On the other hand function will not see any variable from other function (main too). If you want so, declare global variables (not recommended).
#include <stdio.h>
#include <conio.h> //libraries
void function1(int);
float function2(float); //declaration of functions
int main()
{
char decision;
printf("press 'a' to run function1, press 'b' to run function2\n");
decision=getch(); //first see getch()? look in google for functionality and library !
int someInt=10;
float someFloat=11;
if(decision== 'a')
{
function1(someInt);
}
else if(decision == 'b')
{
printf("%f", funcion2(someFloat)); //example that function become what they return
}
else
{
printf("No decision has been made");
}
getch(); //program will wait for any key press
return 0;
}
void function1(int param1)
{
//print your stuff // this function return void, so doesnt have return; statement
}
float function2(float param1)
{
return 2*param1; //this function have to return some float
}

Why does this variable value return to default value after exiting the function?

I want to move the knight in a chess program. For this reason,
I have these two variables(currentRow and currentColumn) defined on top of all functions including main. (I did this because I wanted these variables as global variables to all functions) as below. Because when the knight moves, its position will change. And this will be the input to its next move.
What I don't understand is when I debug, I saw that these variables are changing in the function but as soon as it exits function, they return to their default values (3 and 4).
Can you tell me how to fix this? Thanks in advance...
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
int currentRow=3;
int currentColumn=4;
int main(void){
...
}
int checkIsEmptyandMoveAccordingly(int moveNumber, int currentRow, int currentColumn){
if (chessBoard[currentRow+vertical[moveNumber]][currentColumn+horizontal[moveNumber]]==0 && currentRow+vertical[moveNumber]>=0 && currentColumn+horizontal[moveNumber] >=0 ){ //if empty,move to new location
currentRow+=vertical[moveNumber];
currentColumn+=horizontal[moveNumber];
printf("Move randomised to: %d\n", moveNumber);
printf("Knight has moved to chessBoard[%d][%d].\n",currentRow,currentColumn);
count++;
printf("Move count is %d.\n",count);
chessBoard[currentRow][currentColumn]=1;
if(!checkIsAroundFUll()){
moveNumber=randomiseMovement();
return moveNumber;
}
else {
printf("ALL TARGET SPACES ARE VISITED BEFORE. KNIGHT CAN NOT MOVE\n PROGRAM WILL BE TERMINATED!!!\n");
return -1;
}
}
else if (chessBoard[currentRow+vertical[moveNumber]][currentColumn+horizontal[moveNumber]]==1) { //if not empty, randomise again
printf("Knight CAN NOT MOVE! Target SPACE IS OCCUPIED\n");
if(!checkIsAroundFUll()){
moveNumber=randomiseMovement();
return moveNumber;
}
else {
printf("ALL TARGET SPACES ARE VISITED BEFORE. KNIGHT CAN NOT MOVE\n PROGRAM WILL BE TERMINATED!!!");
return -1;
}
}
else {
printf("OUT OF BOUNDS!! CAN NOT MOVE. TRYING ANOTHER MOVEMENT");
if(!checkIsAroundFUll()){
moveNumber=randomiseMovement();
return moveNumber;
}
else {
printf("ALL TARGET SPACES ARE VISITED BEFORE. KNIGHT CAN NOT MOVE\n PROGRAM WILL BE TERMINATED!!!");
return -1;
}
}
}
int currentRow, int currentColumn are in the function parameter list, so they are local variables. They are hiding the global ones with the same names.
Your function has new variables currentRow and currentColumn declared as parameters to the function. If you want to update the global variables, remove these parameters (and don't pass them when you call the function) and you should see the globals update.
What you're doing is shadowing the global variables. With the right compiler warning enabled (which varies by compiler) you would be told about this error.
Try compiling with -Wall -Werror if you are using gcc.
Your function is changing local copies. When you pass them to the function, they pass by value, the function creates local copies, and the local scope overrides the global scope. If you want to reference global variables, don't pass them into your function, just access them from there.

Resources