Dynamic memory in C with struct - c

I've got this code, but it doesnt work, what's wrong?
I try to make massive of struct with dynamic size(C language)
after the second use of add_sala(); in main function Windows close programm.
Please help to solve this problem! Thanks!
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <malloc.h>
char trash[50];
int dyn_sala_id=1;
typedef struct
{
int id;
char number[6];
int persons;
char tech_inf[256];
} sala;
sala *sala_;
int add_sala()
{
int persons;
char number[6], tech_inf[256];
sala_ = (sala*)realloc(sala_,dyn_sala_id * sizeof(sala));
printf("Wpisz numer sali(max. 5 znakow): ");
fgets(number,6,stdin);
if(strlen(number)>5)
{
printf("Numer musi byc nie wiecej, niz 5 znakow!\n");
fflush(stdin);
add_sala();
return 0;
}
printf("Wpisz ilosc osob, ktora wmiesci sie w sale(max. 1000 osob): ");
scanf("%d", &persons);
if(persons==0 || persons>1000)
{
printf("Nie wolno wprowadzic litery oraz max. ilosc osob to 1000\n");
fflush(stdin);
add_sala();
return 0;
}
printf("Wpisz info o wyposazeniu sali(max. 255 znakow): ");
fgets(trash,50,stdin);
fgets(tech_inf,256,stdin);
if(strlen(tech_inf)>255)
{
printf("Info musi byc nie wiecej, niz 255 znakow!\n");
fflush(stdin);
add_sala();
return 0;
}
sala_[dyn_sala_id].id = dyn_sala_id;
strncpy(sala_[dyn_sala_id].number, number, 6);
sala_[dyn_sala_id].persons = persons;
strncpy(sala_[dyn_sala_id].tech_inf, tech_inf, 256);
printf("\nSala zostala dodana!\n\n");
printf("%d, %d, %s, %s",dyn_sala_id, persons, number, tech_inf);
dyn_sala_id+=1;
return 0;
}
int main()
{
add_sala();
printf("%s",sala_[1].number);
add_sala();
printf("'%s'",sala_[1].number);
printf("'%s'",sala_[2].number);
return 0;
}

Arrays in C are indexed from 0, so in main() the array indexing is off by 1.
add_sala();
printf("%s",sala_[1].number);
add_sala();
printf("'%s'",sala_[1].number);
printf("'%s'",sala_[2].number);
Also in the function add_sala() it is clear that the first time it is called you have the global
int dyn_sala_id=1;
which you use to allocate memory for one record with
sala_ = (sala*)realloc(sala_,dyn_sala_id * sizeof(sala));
but a bit further down, the indexing is again off by 1, where there is plainly only one array element
sala_[dyn_sala_id].id = dyn_sala_id;
Then, in that same function (although I can't read the error messages) it seems strange that after an apparent bad input, you recurse the function. Also, you have undefined behaviour with
fflush(stdin);
and I have not looked further, because the code will not work.

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;
}

Structur Pointer C

I know I for sure misunderstand how to use pointers again. So here is my code. Would be nice if you all can help me. The program is simple. You write values in a structure array and print them out. Even so it would be nice if someone could explain to me when to use double pointers and how to use them probably.
#include <stdio.h>
#include <stdlib.h>
#define MAXA 3
typedef enum{
FOOD,
ART,
OTHERS
}TKindOfArticle;
typedef struct{
int number;
char description[31+1];
int sellingGrossPrice;
int vat;
int minimumStockLevel;
TKindOfArticle kindOf;
}TArticle;
void readOneArticle(TArticle* arti);
int readMaxArticle(TArticle* arti[]);
void printfOneArticle(TArticle arti);
void printfMaxArticle(TArticle *arti[],int read);
int main()
{
TArticle arti[MAXA];
int howMany;
howMany = readMaxArticle(&arti);
printfMaxArticle(&arti,howMany);
return 0;
}
void readOneArticle(TArticle* arti){
printf("Number: ");
scanf("%d", &(arti->number));
printf("Descrip: ");
scanf("%s", &(arti->description));
printf("SellGrossPrice: ");
scanf("%d",&(arti->sellingGrossPrice));
printf("MinimumStock: ");
scanf("%d",&(arti->minimumStockLevel));
printf("Kind of article (0: Food, 1: Art, 2: Others): ");
scanf("%d",&(arti->kindOf));
if(arti->kindOf == FOOD){
arti->vat= arti->sellingGrossPrice*1.1;
} else if(arti->kindOf == ART){
arti->vat= arti->sellingGrossPrice*1.13;
}else if(arti->kindOf == OTHERS){
arti->vat= arti->sellingGrossPrice*1.2;
}
}
int readMaxArticle(TArticle* arti[]){
int read;
int i=0;
printf("Max Elements (max. 3): ");
scanf("%d",&read);
if(read>MAXA){
printf("Error");
} else{
for(i=0; i<read;i++){
readOneArticle(arti[i]);
printf("\n");
printf("Number: %d\nDescrip.: %s\nSell Gross: %d\nVat: %d\nMin. Stock: %d\n",
(*arti[i]).number,(*arti[i]).description,
(*arti[i]).sellingGrossPrice,(*arti[i]).vat,(*arti[i]).minimumStockLevel);
}
}
return read;
}
void printfOneArticle(TArticle arti){
printf("Number: %d\nDescrip.: %s\nSell Gross: %d\nVat: %d\nMin. Stock: %d\n",
arti.number,arti.description,
arti.sellingGrossPrice,arti.vat,arti.minimumStockLevel);
switch(arti.kindOf){
case 0: printf("Kind: Food\n");
break;
case 1: printf("Kind: Art\n");
break;
case 2: printf("Kind: Others\n");
break;
}
}
void printfMaxArticle(TArticle *arti[],int read){
if(read>MAXA){
} else{
for(int i=0; i<read;i++){
printfOneArticle(*arti[i]);
printf("\n");
}
}
}
You are creating an array of structures: TArticle arti[MAXA];
But when you call readMaxArticle(&arti) function you pass pointer to array of TArticle. TArticle *arti[] it reads like this - arti is array of pointers to TArticle. But you want to pass pointer to array of TArticle. It won't compile anyway.
error: cannot convert 'TArticle (*)[3]' to 'TArticle**'
You might want to look at how to read C declaration and if you want to practice visit this site.

Problem when trying to copy a struct in C

So I am starting to use C, and I have some problems almost always with memory allocation. Basically I am getting stuck when I am trying to copy a struct to another struct.
I will put you the code here:
The headers file is:
#include <stdio.h>
#include <stdbool.h>
#include <string.h>
//declaration constants
#define MAX_NAME 15+1
#define SEATS_PERCENTAGE 0.95
#define IN_TIME 60
#define OUT_TIME 120
//type declarations
typedef enum {FORBIDDEN, ALLOWED_WITH_COMPANION, ALLOWED} tFairgroundRideAccess;
typedef struct{
tFairgroundRideAccess lessThan100;
tFairgroundRideAccess between100_120;
tFairgroundRideAccess between120_140;
tFairgroundRideAccess greaterThan140;
} tFairgroundRideHeightRequirement;
typedef struct {
char name[MAX_NAME];
tFairgroundRideHeightRequirement accessHeight;
int durationTrip;
int numPersonsTrip;
int peopleInQueue;
} tFairgroundRide;
tFairgroundRide myFairgroundRide;
//define function headers
void readFairgroundRide(tFairgroundRide *fRide);
void writeFairgroundRide(tFairgroundRide fRide);
void copyFairgroundRide(tFairgroundRide fRideSrc, tFairgroundRide *fRideDst);
int waitingTime (tFairgroundRide fRide, int people);
bool accessWithoutCompanion (tFairgroundRide fRide, int height);
void selectFairgroundRide (tFairgroundRide fRide1, tFairgroundRide fRide2, int people1, int people2, int height2);
The file with the functions is the following one (what I want to check why I am not allocating properly in memory the new copy in the function copyFairgroundRide):
#include <stdio.h>
#include <stdbool.h>
#include <string.h>
#include "fairgroundRide.h"
void readFairgroundRide(tFairgroundRide *fRide){
printf("NAME >> \n");
scanf("%s", fRide->name);
getchar();
printf("ACCESS HEIGHT, LESSTHAN100 (0-FORBIDDEN, 1-ALLOWED_WITH_COMPANION, 2-ALLOWED) >> \n");
scanf("%d", &fRide->accessHeight.lessThan100);
getchar();
printf("ACCESS HEIGHT, BETWEEN100_120 (0-FORBIDDEN, 1-ALLOWED_WITH_COMPANION, 2-ALLOWED) >> \n");
scanf("%d", &fRide->accessHeight.between100_120);
getchar();
printf("ACCESS HEIGHT, BETWEEN120_140 (0-FORBIDDEN, 1-ALLOWED_WITH_COMPANION, 2-ALLOWED) >> \n");
scanf("%d", &fRide->accessHeight.between120_140);
getchar();
printf("ACCESS HEIGHT, GREATERTHAN140 (0-FORBIDDEN, 1-ALLOWED_WITH_COMPANION, 2-ALLOWED) >> \n");
scanf("%d", &fRide->accessHeight.greaterThan140);
getchar();
printf("TRIP DURATION >> \n");
scanf("%d", &fRide->durationTrip);
getchar();
printf("NUMBER OF PERSONS ON A TRIP >> \n");
scanf("%d", &fRide->numPersonsTrip);
getchar();
}
void writeFairgroundRide(tFairgroundRide fRide){
printf("NAME: %s\n", fRide.name);
printf("ACCESS HEIGHT, LESSTHAN100 (0-FORBIDDEN, 1-ALLOWED_WITH_COMPANION, 2-ALLOWED): %d\n",fRide.accessHeight.lessThan100);
printf("ACCESS HEIGHT, LESSTHAN100 (0-FORBIDDEN, 1-ALLOWED_WITH_COMPANION, 2-ALLOWED): %d\n",fRide.accessHeight.between100_120);
printf("ACCESS HEIGHT, LESSTHAN100 (0-FORBIDDEN, 1-ALLOWED_WITH_COMPANION, 2-ALLOWED): %d\n",fRide.accessHeight.between120_140);
printf("ACCESS HEIGHT, LESSTHAN100 (0-FORBIDDEN, 1-ALLOWED_WITH_COMPANION, 2-ALLOWED): %d\n",fRide.accessHeight.greaterThan140);
printf("TRIP DURATION: %d\n", fRide.durationTrip);
printf("NUMBER OF PERSONS ON A TRIP: %d\n", fRide.numPersonsTrip);
}
void copyFairgroundRide(tFairgroundRide fRideSrc, tFairgroundRide *fRideDst){
strcpy(fRideDst->name,fRideSrc.name);
fRideDst->accessHeight.lessThan100 = fRideSrc.accessHeight.lessThan100;
fRideDst->accessHeight.between100_120 = fRideSrc.accessHeight.between100_120;
fRideDst->accessHeight.between120_140 = fRideSrc.accessHeight.between120_140;
fRideDst->accessHeight.greaterThan140 = fRideSrc.accessHeight.greaterThan140;
fRideDst->durationTrip = fRideSrc.durationTrip;
fRideDst->numPersonsTrip = fRideSrc.numPersonsTrip;
fRideDst->peopleInQueue = fRideSrc.peopleInQueue;
}
int waitingTime (tFairgroundRide fRide, int people){
int result;
result = ((IN_TIME+OUT_TIME+(fRide.durationTrip*60)) * (fRide.numPersonsTrip * SEATS_PERCENTAGE) * people);
return result;
}
bool accessWithoutCompanion (tFairgroundRide fRide, int height){
if (height < 100 && fRide.accessHeight.lessThan100 == 2){
return true;
}
if(height >= 100 && height<120 && fRide.accessHeight.between100_120 == 2){
return true;
}
if(height >= 120 && height<=140 && fRide.accessHeight.between120_140 == 2){
return true;
}
if (height > 140 && fRide.accessHeight.greaterThan140 == 2){
return true;
}else{
return false;
}
}
void selectFairgroundRide (tFairgroundRide fRide1, tFairgroundRide fRide2, int people1, int people2, int height2){
if((accessWithoutCompanion(fRide1,height2) == true) && (waitingTime(fRide1,people1)<=waitingTime(fRide2,people2))){
copyFairgroundRide(fRide1,&myFairgroundRide);
}
if((accessWithoutCompanion(fRide1,height2) == true) && (accessWithoutCompanion(fRide2,height2)==false)){
copyFairgroundRide(fRide1,&myFairgroundRide);
}
if((accessWithoutCompanion(fRide1,height2) == false) && (accessWithoutCompanion(fRide2,height2))){
copyFairgroundRide(fRide2,&myFairgroundRide);
}
}
And the main code is:
#include <stdio.h>
#include <stdbool.h>
#include <string.h>
#include "fairgroundRide.h"
int main(){
tFairgroundRide myFairgroundRide;
tFairgroundRide fairgroundRide1;
tFairgroundRide fairgroundRide2;
int height1,people1,people2;
printf("ENTER DATA FOR FIRST FAIRGROUND RIDE >>\n");
readFairgroundRide(&fairgroundRide1);
printf("ENTER THE PEOPLE IN THE QUEUE OF FAIRGROUND RIDE 1 >> \n");
scanf("%d", &people1);
getchar();
printf("ENTER DATA FOR SECOND FAIRGROUND RIDE >>\n");
readFairgroundRide(&fairgroundRide2);
printf("ENTER THE PEOPLE IN THE QUEUE OF FAIRGROUND RIDE 2 >> \n");
scanf("%d", &people2);
getchar();
printf("ENTER THE HEIGHT >> \n");
scanf("%d", &height1);
getchar();
selectFairgroundRide(fairgroundRide1,fairgroundRide2,people1,people2,height1);
printf("RESULTS:\n");
writeFairgroundRide(myFairgroundRide);
getchar();
return 0;
}
So when I am running the program I can get all the info of both inputs, faigroundRide1 and fairgroundRide2, but if I copy it to another struct called myFairgroundRide I start getting weird characters and numbers, and I know that is due to memory allocation but I cannot find why or where is the issue. If you need further explanations about the code or what is my doubt just let me know and I will try to re-do it in another way.
Thanks in advance,
Jorge.
You have two myFairgroundRide. One in global scope, and one as local variable in main. In selectFairgroundRide you copy to the global one, but later in main you print the local one.
And by the way, copyFairgroundRide can be simplified:
void copyFairgroundRide(tFairgroundRide fRideSrc, tFairgroundRide *fRideDst)
{
*fRideDst = fRideSrc;
}

how to break from the function?

I have the void function void isVaraRegistered that should check for existent numbers in the array that are introduced as varanummer in regVaror. If the introduced number already exists it should break from the regVaror function. I am not sure how to do it. How to set isVaraRegistered to true or false or any combination in fact. Please help!
//lager program lab
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdbool.h>
#define DEPOSIT 10
#define WORDLENGTH 30
#define MAX 10
struct varor{
int varunummer;
char namn[WORDLENGTH];
int lagersaldo;
};
typedef struct varor Vara;
Vara createVara(int varunummer, char namn[], int lagersaldo){
Vara v;
v.varunummer=varunummer;
strcpy(v.namn, namn);
v.lagersaldo=lagersaldo;
return v;
}
void isVaraRegistered(Vara reg[], int varunummer){
for(int n=0; n<MAX; n++){
if(reg[n].varunummer==varunummer) {
printf("\nError! Varunummer finns redan!\n\n");
}
break;
}
}
void regVaror( Vara reg[], int *pNrOfVaror){
char confirm;
char namn[WORDLENGTH],
tmp[WORDLENGTH];
int varunummer, lagersaldo;
printf("\nÄr du säkert att du vill registrera nya varor?\n1: Ja - (fortsätt)\n2: Nej - (gå tillbaka till menyn)\n");
scanf(" %c%*c", &confirm);// %*c för att inte skippa raden dvs skipppa ange varunummer
switch(confirm){
case '1':
do{
printf("Ange varunummer:");
gets(tmp);
varunummer=atoi(tmp);
isVaraRegistered(reg,varunummer);
printf("Ange namn:");
gets(namn);
printf("Ange lagersaldo:");
gets(tmp);
lagersaldo=atoi(tmp);
reg[*pNrOfVaror]=createVara(varunummer,namn,lagersaldo);
(*pNrOfVaror)++;
printf("\nRegristrera mer varor?\n1: Ja - (fortsätt)\n2: Nej - (gå tillbaka till menyn)\n");
scanf(" %c%*c", &confirm);
}while(confirm=='1');
case '2': break;
}
}
int main(){
int run=1;
Vara vRegister[MAX];
int nrOfVaror=0;
while(run){
char choice;
printf("\n\t\tMeny - Lager Program\n\n\
(1) Regristrera nya varor\n\b\b\b\b\
(2) Skriva ut alla varor\n\
(3) Söka efter varor\n\
(4) Ändra lagersaldot för varor\n\
(5) Sortera varor\n\
(6) Avregristrera varor\n\
(7) Avsluta programmet\n");
scanf(" %c%*c", &choice);
if(choice=='1') regVaror(vRegister, &nrOfVaror);
else if(choice=='7') run=0;
}
return 0;
}
A straight return will do it, but I tend to lean towards a more controlled exit in exceptional situations and let the function run through. Obviously there are scenarios where it's fine to have multiple returns but I try to keep it to a guard at the beginning and maybe a couple of special circumstances prior to finishing. But I wouldn't return from inside a loop. Just makes me feel dirty :)
So in your situation I would actually break as you are doing already which will return anyway... Your code is fine. But I'd lean towards this approach:
void isVaraRegistered(Vara reg[], int varunummer){
int found = 0;
for(int n=0; found == 0 && n<MAX; n++){
if(reg[n].varunummer==varunummer) {
printf("\nError! Varunummer finns redan!\n\n");//existing error msg
found++;
}
}
}
Note that this is just a personal coding style thing. Moving over to C# a few years ago thee was a push in our company to standardise and write a certain way and this sort of controlled execution of letting the full function run through was preferred.
--- Edit:
I was responding to the original code, you've updated since I started responding.
Incidentally, should should set int as your return type and return 1 or 0 indicating yes or no given the name of the function and return the found variable I introduced. Then where the function is called respond accordingly....and take out the printf as the function itself has one responsibility which is to answer the question 'isVaraRegistered?'. Any user I/O should be done outside this function.

Trying to print a struct element but getting blank. - C

I have a struct person that has the following elements, defined in data.h
typedef struct person{
char firstName[20];
char familyName[20];
char telephoneNum[20];
int type; // 0 = student / 1 = employee;
}newPerson;
I created an array of person[MAX_PERSONS] that is initialized in my menu() function. I then have an addFirstName(newPerson pers) function. However when I try to test print format using my printFormat(newPerson pers)function, I get blank, instead of the inputted name.
I have included the menu(), addFirstname(newPerson pers), and printFormat(newPerson pers) function below. I was wondering if anyone could tell me the reason for this. Any help or pointers would be appreciated. Thank you in advance.
int menu(){
int num = 0;
newPerson person[MAX_PERSONS];
int option; // for user input for menu
printf("\n\tPlease choose one of the following options to continue (0-9): ");
scanf("%d", &option );
printf("\n\tYou selected %d\n", option);
if (option == 0){ //program will close
printf("\tProgram will now close.\n");
exit(1);
}
if (option == 1){ //program will ask for name input
addRecord(person[num]);
printFormat(person[num]);
char choice[0];
printf("\n\t\tWould you like to enter another record? (y/n): ");
scanf("%s", choice);
if (choice[0] == 'y'){
num++;
addRecord(person[num]);
}
if (choice[0] == 'n'){
num++;
mainMenu();
}
/*
IF YES, THEN NUM++
THEN RUN ADDRECORD(PERSONNUM) AGAIN.
IF NO, THEN RETURN TO MAIN MENU.
PRINTMENU
THEN RUN MENU AGAIN
*/
}
printf("\n\tNot a valid option, please try again // THE END OF MENU FUNCTION\n");
return 0;
}
void addFirstName(newPerson pers){
char firstName[20];
printf("\n\tEnter first Name: ");
scanf("%20s", firstName);
strcpy(pers.firstName, firstName);
printf("\n\tThe name entered is %s", pers.firstName);
}
void printFormat(newPerson pers){
printf("\t\tThe name is %s", pers.firstName);
}
It's because you pass the structure to addFirstName by value meaning that the function receives a copy of the structure. And changing a copy will of course not change the original.
While C does not support passing arguments by reference, it can be emulated using pointers. So change the addFirstName function to receive a pointer to the structure as its argument.
Your big problem is that you are passing structures by value instead of by pointers. This result in that you change copies of original objects inside your function addFirstName and not the original object. You should declare it as:
void addFirstName( newPerson* pers);
void printFormat( newPerson* pers);
Example:
#include <stdio.h>
void call_by_value(int x) {
printf("Inside call_by_value x = %d before adding 10.\n", x);
x += 10;
printf("Inside call_by_value x = %d after adding 10.\n", x);
}
int main() {
int a=10;
printf("a = %d before function call_by_value.\n", a);
call_by_value(a);
printf("a = %d after function call_by_value.\n", a);
return 0;
}
this will produce:
a = 10 before function call_by_value.
Inside call_by_value x = 10 before adding 10.
Inside call_by_value x = 20 after adding 10.
a = 10 after function call_by_value.

Resources