Function casts itself c, after it has been casted twice - c

I've got a university project where I have to write a database of workers. I decided to use dynamic array of structures:
struct data
{
char id[50];
char name[50];
char surname[50];
char account_num[50];
double net_pension,taxed_pension;
};
int main()
{
int current_size=0;
struct data *database;//creating a table
database=(struct data*)malloc(1*sizeof(struct data));//memory allocation
menu(database);//running menu
return 0;
}
function menu
void menu(struct data *database)
{
int current_size=1;
int input=0;
char inpt[512];
do
{
printf("Input function or input help for list of avaible commands \n");
fgets(inpt,511,stdin);
input=mod_input(inpt);
if(input==404)
{
printf("Function does not exist \n");
}
else if(input==1)
{
print_result(database,current_size);
}
else if(input==2)
{
add_element(database,&current_size);
}
else if(input==3)
{
modify_element(database,current_size);
}
else if(input==4)
{
sort_table(database, current_size);
}
else if(input==5)
{
search(database,current_size);
}
else if(input==6)
{
hilfe();
}
else if(input==7)
{
search_by_col(database,current_size);
}
input=8;
}
while(input!=0);
}
decides what we want to do, for example writing "add" will start my problematic function, which is supposed to add new records
void add_element(struct data *database,int *size)
{
int subflag=0;
char inpt[50];
int place=((*size)-1);
int pass=(*size);
printf("%i",pass);
if((*size)!=1)
{
modify_element(database,(*size));
}
do
{
printf("Input unical ID \n");
fgets(inpt,50,stdin);
if(does_exist(inpt,database,pass)==1)
{
subflag=1;
strncpy(database[place].id,inpt,50);
}
else
{
printf("ID exists");
}
}
while(subflag==0);
subflag=0;
do
{
printf("Input name \n");
fgets(inpt,50,stdin);
if(is_word(inpt)==1)
{
subflag=1;
strcpy(database[place].name,inpt);
}
}
while(subflag==0);
subflag=0;
do
{
printf("Input surname \n");
fgets(inpt,50,stdin);
if(is_word(inpt)==1)
{
subflag=1;
strcpy(database[place].surname,inpt);
}
}
while(subflag==0);
subflag=0;
do
{
printf("Input account number \n");
fgets(inpt,50,stdin);
if(is_accnum(inpt)==1)
{
subflag=1;
strcpy(database[place].account_num,inpt);
}
}
while(subflag==0);
subflag=0;
do
{
printf("Input net gain \n");
fgets(inpt,50,stdin);
if(is_num(inpt)==true)
{
printf("%d",atof(inpt));
subflag=1;
database[place].net_pension=atof(inpt);
}
}
while(subflag==0);
subflag=0;
do
{
printf("Input taxed gain \n");
fgets(inpt,50,stdin);
if(is_num(inpt)==true)
{
subflag=1;
database[place].taxed_pension=atof(inpt);
}
}
while(subflag==0);
printf("record added \n");
if((*size)==1)
(*size)++;
}
function modify_size reallocs memory, does_exist ensures, that id's are unique, is acc_num, num and word checks input for given rules. They all work perfectly when you use function first time. But after you try to add second one "record added" does not display and function add runs from the beginning. I ahve no idea why. That is the main problem. Secondary one is menu, because when you input "print" it runs add_element. Code that converts input is:
int mod_input(char function[])
{
printf(function);
if(strcmp(function,"modify")==1)
return 3;
else if(strcmp(function,"sort")==1)
return 4;
else if(strcmp(function,"search")==1)
return 5;
else if(strcmp(function,"help")==1)
return 6;
else if(strcmp(function,"add")==1)
return 2;
else if(strcmp(function,"print")==1)
return 1;
else if(strcmp(function,"search_by_column")==1)
return 7;
return 404;
}
Thank you in advance for help. Also I know that some parts could be done better, but for now, I try to just force it to work.
whole programme
lab3.c and header

Intuitively, what you need to do is pass around a pointer to a pointer to your array, not just a pointer to it. And that's what BLUEPIXY was trying to get at in a comment.
The problem is that if you do x = realloc(y, new_size), there's no guarantee that x will be equal to y.
In particular, database = realloc(database, new_size) inside a subroutine may leave the subroutine with a different value for database than the one passed in as an argument. The caller still has the old value for database.
The results are undefined, and may include worse than what you got.
What you want is something like
struct data *datap;
struct data **database = &datap;
*database = malloc(sizeof(struct data))
With corresponding changes all the way down - basically pass database, and set *database = realloc(...) when you get to that stage.
Also, make sure you update *size appropriately at the same time.

Related

String in structure gets deleted

I'm working on the last exercise of the "Think like a computer scientist, C version" book and I have some trouble with one particular point.
The exercise consists of making a small game, where the computer picks a random value between 0 and 20 and then asks me to guess the number.
After that, the computer counts the number of tries I made and, if I get a better score than the previous party, I need to store my name and the number of tries in a structure.
My problem is the following: When I restart the game, the string value, player_name, in the structure gets somehow deleted but player_score is still there.
First, I made a "call by value" function to create the structure and then a tried with a "call by reference" but getting the same results.
I think I tried everything I could with my actual knowledge for now; so, if someone could check my code and give me some tips about what's wrong I would much appreciate it!
//HEADERS
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#define FALSE 0
#define TRUE 1
//TYPEDEF STRUCTS
typedef struct
{
int player_score;
char *player_name;
} HS_Player;
//FUNCTION PROTOTYPES
int Random_Value(void);
int Get_User_Choice(void);
int Check_Result(int computer, int my_choice);
int Try_Again(int game_result, int computer);
void Player_Infos(HS_Player *player_p, int score);
int Game_Restart(void);
//MAIN
int main(void)
{
int end_game;
int high_score_value = 100;
HS_Player player;
while (end_game != TRUE)
{
int computer_number = Random_Value();
printf("Guess the number between 0 et 20 chosen by the computer.\n");
int your_number = Get_User_Choice();
int result_game = Check_Result(computer_number, your_number);
int tries_to_win = Try_Again(result_game, computer_number);
printf("Number of tries: %i\n", tries_to_win);
if (tries_to_win < high_score_value)
{
Player_Infos(&player, tries_to_win );
high_score_value = player.player_score;
}
printf("Highest score: %i By: %s\n", player.player_score, player.player_name);
printf("\n");
end_game = Game_Restart();
}
return EXIT_SUCCESS;
}
//Random_Value FUNCTION
int Random_Value(void)
{
srand(time(NULL));
int x = rand();
int y = x % 20;
return y;
}
//Get_User_Choice FUNCTION
int Get_User_Choice(void)
{
int success, x;
char ch;
printf("Your Guess:\t");
success = scanf("%i", &x);
while (success != 1)
{
printf("Your input is not a number. Please try again:\t");
while ((ch = getchar()) != '\n' && ch != EOF);
success = scanf("%i", &x);
}
if (x < 0 || x > 20)
{
printf("Your input must be between 0 and 20. Please try again.\n");
Get_User_Choice();
}
return x;
}
//Check_Result FUNCTION
int Check_Result(int computer, int my_choice)
{
int check_result;
if (my_choice < computer)
{
printf("Computer number is larger!\n");
check_result = FALSE;
}
else if (my_choice > computer)
{
printf("Computer number is smaller!\n");
check_result = FALSE;
}
else if (my_choice == computer)
{
printf("It's a Match! You chose the same number than the computer.\n");
printf("\n");
check_result = TRUE;
}
return check_result;
}
//Try_Again FUNCTION
int Try_Again(int game_result, int computer)
{
int tries_befor_success = 1;
while (game_result != TRUE)
{
int your_number = Get_User_Choice();
game_result = Check_Result(computer, your_number);
tries_befor_success++;
}
return tries_befor_success;
}
//Player_Infos FUNCTION
void Player_Infos(HS_Player *player_p, int score)
{
char new_name[80];
printf("Congrats! Your made a new high score.\n");
printf("What's your name ?\t");
scanf("%s", new_name);
printf("\n");
player_p->player_score = score;
player_p->player_name = new_name;
}
//Game_Restart FUNCTION
int Game_Restart(void)
{
int quit_value;
printf("Quit Game ?\n");
printf("Press 'y' to quit or any other keys to continue.\n");
fflush(stdin);
char quit_game = getchar();
printf("\n");
if (quit_game == 'y')
{
quit_value = TRUE;
}
else
{
quit_value = FALSE;
}
return quit_value;
}
The problem is that, in your Player_Infos function, you are assigning the address of a local array to the char* player_name pointer member of the passed structure. When that function ends, the local array it used will be deleted and the pointer in the structure will be invalid. (In the case of the player_score, you don't have that problem, because the given value is copied to the structure member.)
There are several ways around this; one would be to use the strdup() function to make a copy of the local char new_name[80]; array – but that is really overkill, and you would need to manage (i.e. free()) that allocated string whenever you make a modification.
A simpler way is to make the player_name member an actual array of char and then use strcpy() to copy the local array into that member.
Better, still, with the player_name member defined as char [80], you can read directly into that (in the function), and avoid the local array completely:
typedef struct
{
int player_score;
char player_name[80];
} HS_Player;
//...
void Player_Infos(HS_Player *player_p, int score)
{
printf("Congrats! Your made a new high score.\n");
printf("What's your name ?\t");
// Read directly. Limit input to 79 chars (allowing room for null terminator).
scanf("%79s", player_p->player_name);
printf("\n");
player_p->player_score = score;
}
Also, just as a "style" tip, you may want to change the member names to just score and name, as the "player" part is implied by the structure type-name itself.
This issue you are having is that you are associating the player name pointer to a variable that goes out of scope when you leave the "player_Infos" function. What you probably would want to do is define the name as a character array in your structure and then use the "strcpy" call in your function instead. Following is a couple of code snippets illustrating that point.
//TYPEDEF STRUCTS
typedef struct
{
int player_score;
char player_name[80];
} HS_Player;
Then, in your function, use the "strcpy" call.
//Player_Infos FUNCTION
void Player_Infos(HS_Player *player_p, int score)
{
char new_name[80];
printf("Congrats! Your made a new high score.\n");
printf("What's your name ?\t");
scanf("%s", new_name);
printf("\n");
player_p->player_score = score;
strcpy(player_p->player_name, new_name);
//player_p->player_name = new_name;
}
When I tested that out, I got a name to appear in the terminal output.
Computer number is smaller!
Your Guess: 4
It's a Match! You chose the same number than the computer.
Number of tries: 8
Highest score: 4 By: Craig
FYI, you will need to include the "string.h" file.
Give that a try.
Name Update
The reason your player.player_name is not getting updated is because you can't assign a string this way in C. When doing player_p->player_name = new_name; you're actually saving in player_p->player_name the memory address of new_name.
Instead, what you want to achieve, is to copy each character of new_name to player_p->player_name and in order to achieve this, you have to change the type of prlayer_name field from char* player_name to char player_name[80], then assign it using, for example, strcpy():
#include <string.h>
// [...]
//TYPEDEF STRUCTS
typedef struct
{
unsigned int player_score;
char player_name[80];
} HS_Player;
// [...]
//Player_Infos FUNCTION
void Player_Infos(HS_Player *player_p, int score)
{
char new_name[80];
printf("Congrats! Your made a new high score.\n");
printf("What's your name ?\t");
scanf("%s", new_name);
printf("\n");
player_p->player_score = score;
strcpy(player_p->player_name, new_name);
}
Data Persistence
To make data (players info) persistent over multiple runs, you have to save the content of the struct to a file.
Example
int Save_Score(char* filename, HS_Player* player)
{
FILE* file = fopen(filename, "w");
if (file == NULL)
{
fprintf(stderr, "\nAn error occurred while opening the file\n");
return -1;
}
if (fprintf(file, "%d %s", player->player_score, player->player_name) < 0)
return -1;
fclose(file);
return 0;
}
int Load_Score(char* filename, HS_Player* player)
{
FILE* file = fopen(filename, "r");
if (file == NULL)
{
fprintf(stderr, "\nAn error occurred while opening the file\n");
return -1;
}
if (fscanf(file, "%d %79s", &player->player_score, player->player_name) < 0)
return -1;
fclose(file);
return 0;
}

Using Struct in C to create a library for items and giving location feedback based upon user entry. I just cant seem to find my error

//make a location marker for key items
#include <stdio.h>
#include <string.h>
struct find {int index; char name[50]; char location[50]; };
int main() {
char locate_item[50];
//using struct to add items
struct find item1;
item1.index = 1;
strcpy(item1.name, "guitar");
strcpy(item1.location, "Usually near the table in the living room area.\n");
struct find item2;
item2.index = 2;
strcpy(item2.name, "ipad");
strcpy(item2.location, "Usually on the table or charging on the bed.\n");
//using while and if statements to get user feedback and display the appropriate location
while (locate_item != item1.name || locate_item != item2.name) {
printf("what is the item you want to find? \n");
scanf("%s", locate_item);
printf("You entered %s\n", locate_item);
if (locate_item == item1.name) {
printf("%s", item1.location);
} else if (locate_item == item2.name) {
printf("%s", item2.location);
} else {
printf("Incorrect entry. Please try again.\n");
}
}
return 0;
}
locate_item != item1.name || locate_item != item2.name compares pointer, however, you want to use strcmp() to compare two strings by value. strcmp() returns 0 if the two strings are the same.
In either case, your program doesn't make a lot of sense. You probably want to find locate_item in the an array of items (renamed from find) along these lines:
#include <stdio.h>
#include <string.h>
struct item {
int index;
char name[50];
char location[50];
};
int main() {
struct item items[] = {
{ 1, "guitar", "Usually near the table in the living room area." },
{ 2, "ipad", "Usually on the table or charging on the bed." },
{ 0 }
};
for(;;) {
printf("what is the item you want to find? \n");
char locate_item[50];
scanf("%s", locate_item);
//printf("You entered %s\n", locate_item);
for(int i = 0; items[i].name[0]; i++) {
if(!strcmp(items[i].name, locate_item)) {
printf("%s\n", items[i].location);
goto done;
}
}
printf("Incorrect entry. Please try again.\n");
}
done:
return 0;
}

Searching for a string in a struct

The code below is a code that will track my product costs and remaining quantity.The problem I'm facing with is I can't search the code by
if(g[n].name == search[10])
The out put keep showing
"Item not found"
Im a beginner of c language and was hope to learn more. Please correct my code and send it here so that I can know why my code is wrong.
#include <stdio.h>
struct product
{
char name[10];
int quantity;
float costs;
};
void fn_search (struct product g[]);
int main ()
{
int n;
struct product g[4];
strcpy(g[0].name,"aa1");
g[0].quantity = 10;
g[0].costs = 1;
strcpy(g[1].name,"bb2");
g[1].quantity = 10;
g[1].costs = 2;
strcpy(g[2].name,"bb3");
g[2].quantity = 10;
g[2].costs = 3;
fn_search (g);
}
void fn_search (struct product g[10])
{
int n;
char search[10];
printf("Search>> ");
scanf("%s",&search[10]);
for (n=0;n<4;n++)
{
if(g[n].name == search[10])
{
printf ("\ncosts = NTD%.2f",g[n].costs);
printf ("\nquantity = %d\n",g[n].quantity);
}
else
{
printf("\nItem not found.");
break;
}
}
}
Two bugs:
Incorrect use of scanf :
scanf("%s",&search[10]); --> scanf("%9s", search);
Note: scanf("%9s", &search[0]); is also fine but the above is the common way.
Incorrect string compare :
if(g[n].name == search[10]) --> if(strcmp(g[n].name, search) == 0)
Also notice that you never initialized g[3] but fn_search checks it.
Then this part:
else
{
printf("\nItem not found.");
break;
}
means that you break the for loop as soon as an item doesn't match. In other words: Currently you only compare against g[0]
You don't want that! Check all items before printing "Item not found".
So the for loop should be more like:
for (n=0;n<4;n++)
{
if(strcmp(g[n].name, search) == 0)
{
printf ("\ncosts = NTD%.2f",g[n].costs);
printf ("\nquantity = %d\n",g[n].quantity);
return; // Exit function when match is found
}
}
// When execution arrives here, there was no matching element
printf("\nItem not found.");
Finally:
void fn_search (struct product g[10])
^^
why ??
Either do
void fn_search (struct product g[])
or
void fn_search (struct product *g)

Allocation to Pointers

I work with char ****pCourses
int Courses(char ****pCourses, int ****pGrades, int **pCount, int *count)
{
char *buffer=NULL;
char letter;
int j=0, i;
int size=20;
int countCourse=0, sumCourses=0;
buffer=(char *)malloc(size*sizeof(char));
do
{
scanf("%c",&letter);
}while(letter==32);
while(letter!=10)
{
while(letter!=',')
{
//in case we need to expend the buffer
if(j>size)
{
size*=2;
buffer=(char *)realloc(buffer,size*sizeof(char));
}
buffer[j]=letter;
j++;
//The new letter from the name of course
scanf("%c",&letter);
}
//The end of the name of course
buffer[j]='\0';
j=0;
if(countCourse==0)
{
*pCount=(int *)realloc(*pCount, ((*count)+1)*sizeof(int));
(*pCount)[*count]=1;
}
else
(*pCount)[*count]++;
//Add the course's name to the system
*pCourses=(char ***)realloc(*pCourses, ((*count)+1)*sizeof(char ***));
(*pCourses)[*count]=(char **)realloc((*pCourses)[*count],(countCourse+1)*sizeof(char *));
((*pCourses)[*count])[countCourse]=(char *)malloc(strlen(buffer)+1);
strcpy(((*pCourses)[*count])[countCourse], buffer);
countCourse++;
scanf("%c",&letter);
}
free(buffer);
return 0;
}
while running I get a problem because of the next line:
(*pCourses)[*count]=(char **)realloc((*pCourses)[*count],(countCourse+1)*sizeof(char *));
that leads me to this part (from dbgheap.c):
{
while (nSize--)
{
if (*pb++ != bCheck)
{
return FALSE;
}
}
return TRUE;
}
does someone know what it means or why does this happen?
I think you've already been told what the problem is. All the alloc-type functions can fail and you should test for that and ideally write code that is robust enough to code with a failure.
Note that repeatedly using realloc() is not a good idea. If you expect to have to repeatedly add ( or remove ) data then you should be using a different structure, like a linked list or tree, which are designed to allow adding and removing data on the fly.

Programming in C, integer distribution error, cannot find mistake

I'm writing a code for a simple text based game, and when I purchase a car, the HP and TOPSPEED are registering for integers different than specified.
I've looked over the code myself, perhaps I'm not seeing it, but the Dodge Intrepid should register at 214hp and 140mph top speed, however when I enter the race menu, it registers for 320hp and 160mph top speed, which are the settings of the Mitsubishi 3000GT and the Dodge Stealth of the last beta. I imported the "race" code from the previous beta, being careful to omit any information about the cars used in the previous beta. If you can find my mistake or point anything out, it would be greatly appreciated (I'm including the code with my post). Thanks for your time. (I'm probably overlooking something) (Written in C, compiled and linked with DevC++)
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
/*HP at RACE is malfunctioning, look over code.*/
int rnd(int range);
void seedrnd(void);
int main()
{
char name[15];
char ocar;
char exit;
char partsA;
char partsB;
char partsC;
char choice;
char dealer;
char model;
int bhp;
int ohp;
int tspd;
int otspd;
int score;
int oscore;
int cash;
int bonus;
int parts1;
int parts2;
int parts3;
int car1;
int car2;
int car3;
int car;
int hp1;
int hp2;
int hp3;
int tspd1;
int tspd2;
int tspd3;
printf("What is your name?\n");
scanf("%s",name);
parts1=1;
parts2=1;
parts3=1;
hp1=214;
tspd1=140;
hp2=490;
tspd2=190;
hp3=320;
tspd3=160;
car=0;
car1=0;
car2=0;
car3=0;
cash=40000;
while(exit!='-')
{
printf("\nMenu:\n1.Garage\n2.Race\n3.Parts Shop\n4.Dealerships\n\n");
choice=getch();
if(choice=='1')
{
printf("Welcome to %s's garage:\n\n",name);
if(car1>0)
{
printf("1.Dodge Intrepid\n");
}
if(car2>0)
{
printf("2.1988 Vector M12\n");
}
if(car3>0)
{
printf("3.Mitsubishi 3000GT\n");
}
car=getch();
if(car=='1')
{
if(car1>0)
{
printf("You are now driving a Dodge Intrepid\n");
car=1;
}
if(car1<1)
{
printf("You do not yet own this vehicle\n");
}
}
if(car=='2')
{
if(car2>0)
{
printf("You are now driving a 1988 Vector M12\n");
car=2;
}
if(car2<1)
{
printf("You do not yet own this vehicle\n");
}
}
if(car=='3')
{
if(car3>0)
{
printf("You are now driving a Mitsubishi 3000GT\n");
car=3;
}
if(car<1)
{
printf("You do not yet own this vehicle\n");
}
}
}
if(choice=='2')
{
if(car=1)
{
bhp=hp1;
tspd=tspd1;
}
if(car=2)
{
bhp=hp2;
tspd=tspd2;
}
if(car=3)
{
bhp=hp3;
tspd=tspd3;
}
/*Begin Race Mechanism*/
printf("Your selected car has %dhp and %dmph top speed\n\n",bhp,tspd);
printf("Now choose your opponent:\n");
printf("1.Rachel (150-250hp 110-130mph)\n");
printf("2.Kyle (250-350hp 130-170mph)\n");
printf("3.Darrian (350-450hp 170-210mph)\n");
printf("4.Chelsea (450-550hp 210-220mph)\n");
ocar=getch();
seedrnd();
if(ocar=='1')
{
ohp=rnd(100)+151;
otspd=rnd(20)+111;
bonus=500;
}
else if(ocar=='2')
{
ohp=rnd(100)+251;
otspd=rnd(40)+131;
bonus=1000;
}
else if(ocar=='3')
{
ohp=rnd(100)+351;
otspd=rnd(40)+171;
bonus=1500;
}
else if(ocar=='4')
{
ohp=rnd(100)+451;
otspd=rnd(10)+211;
bonus=2000;
}
else
{
printf("Haha, you're racing Eli\nNo contest here\n");
ohp=2;
otspd=25;
}
printf("Match-up:%s %dhp %dmph top speed\n",name,bhp,tspd);
printf(" vs \n");
printf("Opponent: %dhp %dmph top speed\n",ohp,otspd);
getch();
score=bhp*tspd;
oscore=ohp*otspd;
printf("Let the race begin\n");
sleep(1000);
printf("3\n");
sleep(1000);
printf("2\n");
sleep(1000);
printf("1\n");
sleep(1000);
printf("!\n\n");
sleep(2000);
printf("The race is over, and the winner is!!!\n\n\n\n");
sleep(3000);
if(score>oscore)
{
printf("YOU!!!\n");
cash=cash+(bonus);
}
else if(score<oscore)
{
printf("Your Opponent...\n");
}
else
{
printf("...neither of you, it was a tie!\n");
cash=cash+(bonus/2);
}
printf("You now have$%d.\n\n",cash);
}/* Closes choice 2*/
if(choice=='3')
{
/* Parts Shop*/
printf("Under Construction\n");
}
if(choice=='4')
{
printf("Press 'y' to exit\n");
printf("Please Select a Dealership\n");
printf("1.Dodge\n2.Vector\n3.Mitsubishi\n\n");
while(dealer!='y')
{
dealer=getch();
if(dealer=='1')
{
printf("DODGE:\n");
if(car1<1)
printf("1.Dodge Intrepid (214hp 140mph) $21,000\n\n");
model=getch();
if(model=='1')
{
if(cash<21000)
{
printf("You cannot afford this vehicle\n\n");
}
if(cash>=21000)
{
if(car1>0)
{
printf("You have already purchased this vehicle\n\n");
}
if(car1<1)
{
car1=car1+1;
cash=cash-21000;
printf("Thank You for purchasing this Dodge Intrepid\n\n");
}
}
}
}
if(dealer=='2')
{
printf("VECTOR:\n");
if(car2<1)
printf("1.1988 Vector M12 (490hp 190mph)$180,000\n\n");
model=getch();
if(model=='1')
{
if(cash<180000)
{
printf("You cannot afford this vehicle\n\n");
}
if(cash>=180000)
{
if(car2>0)
{
printf("You have already purchased this vehicle\n\n");
}
if(car2<1)
{
car2=car2+1;
cash=cash-180000;
printf("Thank You for purchasing this 1988 Vector M12\n\n");
}
}
}
}
if(dealer=='3')
{
printf("MITSUBISHI:\n");
if(car3<1)
printf("1.Mitsubishi 3000GT (320hp 160mph) $60,000\n\n");
model=getch();
if(model=='1')
{
if(cash<60000)
{
printf("You cannot afford this vehicle\n\n");
}
if(cash>=60000)
{
if(car3>0)
{
printf("You have already purchased this vehicle\n\n");
}
if(car3<1)
{
car3=car3+1;
cash=cash-60000;
printf("Thank You for purchasing this Mitsubishi 3000GT\n\n");
}
}
}
}
}
}
exit=getch();
}
return(0);
}
int rnd(int range)
{
int i;
i=rand()%range;
return(i);
}
void seedrnd(void)
{
srand((unsigned)time(NULL));
}
if(car=1)
{
bhp=hp1;
tspd=tspd1;
}
You probably mean if( car == 1 ) { ... this just sets car to 1, and "returns" 1 to the if. Then you do the same for car == 2 and car == 3.
= is the Assignment operator, while == is the comparison operator! The first assigns a value to a variable, while the latter returns true if the are the same (note, for char* you need strcmp()).
Generally you should break your program into small functions and also check for the unhappy case (e.g. what happens if user inputs something not acceptable?)
Another thing that you should pay some attention to is this
scanf("%s",name);
what if someone types in more than 15 characters? You will start righting in memory you do not own and this invokes Undefined Behaviour. One easy trick for that is to do
scanf("%14s", name);
This will restrict the input to 14 characters (and will keep the 15th for the nul terminator). Read more here: http://www.cplusplus.com/reference/clibrary/cstdio/scanf/
As others have noted in the comments, consider using structs to make your life easier. I haven't read the program in too detail to understand the exact structure of your game, but you could have for example a struct for the user:
struct player
{
char name[15];
car* owned_cars; //Linked List!
}
Where car is defined like that:
struct car
{
int max_speed;
int colour; //or even better an enum here
int seats;
//... etc.
car* next_car; //Make the Linked List's next node here!
}
Also! If you make a LinkedList, one mistake that usually happens is that they forgot to initialize thieir pointers to NULL. So :
car* new_car = malloc( sizeof(car) );
new_car->next_car = NULL;
If you don't do that, next_car will contain a random/garbage number! So when you try to go through the List
while(new_car->next_car != NULL)
{
//....
}
You will access memory you do not own.
Good luck and have fun!
There's also an issue in the following code:
if(car=='3')
{
if(car3>0)
{
printf("You are now driving a Mitsubishi 3000GT\n");
car=3;
}
if(car<1) // SHOULD BE car3<1
{
printf("You do not yet own this vehicle\n");
}
}
The integer distribution is wrong, because
int rnd(int range)
{
int i;
i=rand()%range;
return(i);
}
is wrong. That ought to be
int rnd(int range)
{
return rand() / ( RAND_MAX / range + 1 );
}
Read more here: Eternally Confuzzled: using rand()
Edit to the comment:
With this, I specifically respond to your question integer distribution error: the random distribution will not be uniform. Meaning, some numbers will appear significantly less frequently than others, not the property of a true (pseudo) random sequence.
The linked article contains more elaborate explanation of precisely what happens.
You are using the rnd() function defined at the bottom of in quite some places, and to be honest I haven't gone through all the code to understand the implications on what the program does, so I don't know whether it also answers some of the other questions you (vaguely) desscribe in the OP.
This section:
if(car=1)
{
bhp=hp1;
tspd=tspd1;
}
if(car=2)
{
bhp=hp2;
tspd=tspd2;
}
if(car=3)
{
bhp=hp3;
tspd=tspd3;
}
You are assigning car to 1, then 2, then 3: Use == instead of =.

Resources