I can't find my segmentation fault: 11 error - c

I am new to C and wanted to break the series of videos to try a project, but I am stuck on a segmentation error. I get that that means I am trying to access memory I'm not allowed to, but I don't see the issue... I have a lot of code so I'll paste the parts that seem like they might be causing the problem and take out the includes. I am making a command-line text adventure game where two players can choose their name, class, and race (and currently the game ends after it asks them for the input). I appreciate it:
main.c
int main() {
// See term dimesions
// Create Player
struct User* Player;
CreatePlayer(Player);
// Create Player
struct User* Player2;
CreatePlayer(Player2);
return 0;
}
story.c
void CreatePlayer(struct User* Player) {
char name[MAXINPUT];
char class[MAXINPUT];
char race[MAXINPUT];
// Ask for name
printf("%sWhat is your name?\n:\t", KNRM);
getInput(name);
printf("%sHello %s!\n", KNRM, name);
{
// Ask for class
char question[] = "What is your class (Type '1' for Fighter or '2' for Mage)?\n:\t";
char options[] = "12";
char coorilations[][MAXINPUT] = {"Fighter", "Mage"};
questionLoop(question, options, coorilations, class);
InitializeClass(Player, class);
printf("%sYou are now a %s!\n", KNRM, class);
}
{
// Ask for race
char question[] = "What is your race (Type '1' for Human or '2' for Elf)?\n:\t";
char options[] = "12";
char coorilations[][MAXINPUT] = {"Human", "Elf"};
questionLoop(question, options, coorilations, race);
printf("%sYou are now a %s!\n", KNRM, race);
}
strcpy(Player->name, name);
strcpy(Player->race, race);
}
modules.c
void InitializeClass(struct User* Player, char* class) {
if (compare(class, "Fighter")) {
strcpy(Player->class.name, "Fighter");
Player->class.maxHealth = 10;
Player->class.health = 10;
Player->class.strength = 7;
} else if (compare(class, "Mage")) {
strcpy(Player->class.name, "Mage");
Player->class.maxHealth = 7;
Player->class.health = 7;
Player->class.strength = 10;
}
}
void getInput(char res[]) {
int i = 0;
int c;
printf("%s", KMAG);
c = getchar();
while(c != '\n') {
res[i++] = c;
c = getchar();
}
res[i] = '\0';
}
void questionLoop(char question[], char options[], char coorilations[][MAXINPUT], char var[]) {
printf("%s-------------------------------\n", KGRN);
printf("%s%s", KNRM, question);
getInput(var);
for(int i = 0; i < strlen(options); i++) {
if (options[i] == var[0] && var[1] == '\0') {
strcpy(var, coorilations[i]);
printf("%s", KNRM);
return;
}
}
printf("%sSorry that was not an option...\n", KNRM);
questionLoop(question, options, coorilations, var);
}
int compare(char one[], char two[]) {
for (int i = 0; one[i] != '\0'; i++) {
if (one[i] != two[i]) {
return 0;
}
}
return 1;
}
modules.h
#ifndef HEADER_FILE
#define HEADER_FILE
#define MAXINPUT 20
#define KNRM "\x1B[0m"
#define KRED "\x1B[31m"
#define KGRN "\x1B[32m"
#define KYEL "\x1B[33m"
#define KBLU "\x1B[34m"
#define KMAG "\x1B[35m"
#define KCYN "\x1B[36m"
#define KWHT "\x1B[37m"
// Classes
struct Class {
char name[MAXINPUT];
int strength;
int health;
int maxHealth;
};
// User struct
struct User {
char name[MAXINPUT];
char race[MAXINPUT];
struct Class class;
};
// Utilities
void getInput(char res[]);
void questionLoop(char question[], char options[], char coorilations[][MAXINPUT], char var[]);
int compare(char one[], char two[]);
// Game Setup Functions
void CreatePlayer(struct User*);
void InitializeClass(struct User* Player, char* class);
// Game Functions
void GameLoop(struct User*);
void ViewStats(struct User*);
#endif

You never allocate memory for your Player, so from you main method, you call CreatePlayer(), which in turns calls questionLoop(), which does nothing in terms of memory allocations, and then InitializeClass(), which does (amongst others):
strcpy(Player->class.name, "Fighter");
but Player doesn't exist, since you haven't actually create it, you haven't allocated for it, and thus a Segmentation fault occurs (here on the very next lines of that method).
Try dynamically allocating memory using malloc() (e.g. struct User* player = malloc(sizeof(struct User));, and don't forget to free() it when you are done.

This declares a pointer:
struct User* Player;
It is, however, completely uninitialized. It cannot be used before you populate it with something. The CreatePlayer function should assume this responsibility.
Typically these functions look like:
struct User* CreatePlayer() {
struct User *player = malloc(sizeof(struct User));
if (player == NULL) {
return NULL;
}
// Do stuff with player
return player;
}
Where that pattern can be used for any "Create" type function.

Related

Function to add struct to another struct in C

so I have 3 structs here:
typedef struct {
char *name; // allocated
int commonality;
int weight;
} monster;
typedef struct {
char *name; // allocated
char *description; // allocated
double area;
int monsters;
monster **monsters; // allocated
} region;
typedef struct {
char *name; // allocated
double diameter;
int regions;
region **regions; // allocated
} planet;
I already have function:
monster *new_monster(char *name, int commonality, int weight);
I am trying to create these functions:
void add_monster_to_region(region *r, char *mname, int mcommonality, int weight);
void delete_region_from_planet(planet *p, char *rname);
This is what I have so far, but I don't believe it's right, can anyone tell me what I'm doing wrong and how I can fix it?
void add_monster_to_region(region *r, char *mname, int mcommonality, int mweight)
{
for (int i = 0; i < mcommonality; i++)
{
if (strcmp(mname, r->monsters[i]->name) == 0)
{
r->monsters[i]->name = mname;
}
}
}
Thank you
It would be very helpful to have a minimal reproducible example. It would also clarify what was meant with fully allocated NOT a reference array.
Nevertheless, here is my take on how to create a planet, two regions and how to populate the regions with monsters:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
typedef struct {
char *name; // allocated
int commonality;
int weight;
} monster;
typedef struct {
char *name; // allocated
char *description; // allocated
double area;
int monster_count;
monster **monsters; // fully allocated, NOT a reference array
} region;
typedef struct {
char *name; // allocated
double diameter;
int region_count;
region **regions; // fully allocated, NOT a reference array
} planet;
monster *new_monster(char *name, int commonality, int weight) {
monster *new_monster = calloc(sizeof(monster), 0);
if (new_monster != NULL) {
new_monster->name = strdup(name);
if (new_monster->name == NULL) {
free(new_monster);
return NULL;
}
new_monster->commonality = commonality;
new_monster->weight = weight;
}
return new_monster;
}
void free_monster(monster *the_monster) {
if (the_monster != NULL) {
if (the_monster->name != NULL) {
free(the_monster->name);
}
free(the_monster);
}
}
void add_monster_to_region(region *r, char *mname, int mcommonality, int mweight)
{
monster *a_monster = new_monster(mname, mcommonality, mweight);
if (a_monster == NULL) return; // no memory
monster **monsters = NULL;
if (r->monsters != NULL) {
monsters = realloc(r->monsters, (r->monster_count + 1) * sizeof(monster *));
} else {
monsters = calloc(sizeof(monster *), 0);
}
if (monsters == NULL) {
free_monster(a_monster);
return; // no memory
}
r->monsters = monsters;
r->monsters[r->monster_count] = a_monster;
r->monster_count++;
}
void delete_region_from_planet(planet *p, char *rname) {
// TODO
}
int main() {
region desert = {"Desert", "Sunny and warm place.", 50.0, 0, NULL};
region ocean = {"Ocean", "Huge wet place.", 500.0, 0, NULL};
region *regions[] = {&desert, &ocean};
planet mud = {"Mud", 100.00, 2, regions};
add_monster_to_region(&desert, "Bug", 100, 100);
add_monster_to_region(&desert, "Zombie", 10, 20);
add_monster_to_region(&ocean, "Shark", 20, 40);
for (int i = 0; i < mud.region_count; i++) {
for (int j = 0; j < mud.regions[i]->monster_count; j++) {
printf("%s %d %d\n",
mud.regions[i]->monsters[j]->name,
mud.regions[i]->monsters[j]->commonality,
mud.regions[i]->monsters[j]->weight
);
}
}
// TODO: release allocated memory
return 0;
}
We can see all monsters in all regions of the defined planet:
$ gcc -Wall monsters.c
$ ./a.out
Bug 100 100
Zombie 10 20
Shark 20 40
$

trying to add a variable of a certain type inside an array of that type

So i want to create an array of a structure that i made called jogo
Structure:
typedef struct jogo
{
int ident;/*idp of a product*/
char nome[1024]; /* string that describes a team eg. Barcelona */
char *equipas[2]; /*array of strings like {"Barcelona","Madrid"}*/
int score[2]; /*array of strings like {"Barcelona","Madrid"}*/
}* jogo;
I want to create an array without a specific size to store variables of type jogo.
When i type (add) a nome:equipa1:equipa2_score1:score2 like a elclassico:barcelona:madrid:1:0,i want to create a variable of type jogo and store it inside the array sistema_jog.
if i store something and the array is full i want reallocate the size of the array in order to store more variables of type jogo.
But for some reason im always getting segmentation fault core dumped when i try to do it and i dont know why.
Program:
#include<stdlib.h>
#include<stdio.h>
#include <string.h>
#define MAX_CHARS 1024 /* max characters of a word */
#define MAX_SIZE 5
int line = 1; /* counts the number of lines of the stdin */
static int size = MAX_SIZE;
int i = 0; /*ident of the variable jogo*/
int size_until = 0;
typedef struct jogo
{
int ident;/*idp of a product*/
char nome[MAX_CHARS]; /* string that describes a team eg. Barcelona */
char *equipas[2];
int score[2];
}* jogo;
jogo *sistema_jog;
void a(char nome[],char team1[],char team2[],int score1,int score2);
int team_not_in(char team1[],char team2[]);
int nome_in(char nome[]);
void cria_jogo(jogo s,char nome[],char equipa1[],char equipa2[],int score1,int score2);
int main() {
char c; char nome_jg[MAX_CHARS]; char eq1[MAX_CHARS]; char eq2[MAX_CHARS]; int pont1; int pont2;
sistema_jog = (jogo*) calloc(MAX_SIZE,sizeof(jogo));
while ((c = getchar())!= 'x') {
switch (c)
{
case 'a':
{
scanf("%1023[^:\n]:%1023[^:\n]:1023%[^:\n]:%d:%d",nome_jg,eq1,eq2,&pont1,&pont2);
i++;
printf("nome: %s",sistema_jog[0]->nome);
//a(nome_jg,eq1,eq2,pont1,pont2);
break;
}
}
}
return 0;
}
int nome_in(char nome[])
{
int i;
for(i=0; i < size; i++)
{
if (strcmp(sistema_jog[i]->nome,nome) == 0)
return 1;
}
return 0;
}
int team_not_in(char team1[],char team2[])
{
int i;
for (i=0;i<size;i++)
{
if((strcmp(sistema_jog[i]->equipas[0],team1) != 0) || (strcmp(sistema_jog[i]->equipas[1],team2) != 0))
return 1;
}
return 0;
}
void cria_jogo(jogo s,char nome[],char equipa1[],char equipa2[],int score1,int score2)
{
strcpy(s->nome,nome);
strcpy(s->equipas[0],equipa1);
strcpy(s->equipas[1],equipa2);
s->score[0] = score1;
s->score[1] = score2;
}
void a(char nome[],char team1[],char team2[],int score1,int score2)
{
int NL = line;
if (nome_in(nome) == 1)
printf("%d Jogo existente.",NL);
else if (team_not_in(team1,team2) == 0)
{
printf("%d Equipa existente.",NL);
}
else
{
jogo novo_jogo = (jogo) calloc(sizeof(jogo),sizeof(jogo));
cria_jogo(novo_jogo,nome,team1,team2,score1,score2);
if (size_until <= MAX_SIZE)
{
sistema_jog[size_until] = novo_jogo;
size_until++;
}
else
{
sistema_jog = (jogo*) realloc(system, sizeof(jogo)*size_until);
sistema_jog[size_until] = novo_jogo;
size_until++;
}
}
}
I am not surprised that you are confused.
As Christian Gibbons, Barmar and user12986714 said jogo must be your jogostruct and not a pointer to jogo. I supposed you changed, at some stage, } jogo; to }* jogo; because of compilation errors. But, it was not the original problem and after you are confused.
Let me explain shortly, try this basic code :
#include<stdlib.h>
#include<stdio.h>
#include <string.h>
#define MAX_CHARS 1024 /* max characters of a word */
#define MAX_SIZE 5
int line = 1; /* counts the number of lines of the stdin */
static int size = MAX_SIZE;
int i = 0; /*ident of the variable jogo*/
int size_until = 0;
typedef struct jogo
{
int ident;/*idp of a product*/
char nome[MAX_CHARS]; /* string that describes a team eg. Barcelona */
char *equipas[2];
int score[2];
}* jogo;
typedef struct jogo2
{
int ident;/*idp of a product*/
char nome[MAX_CHARS]; /* string that describes a team eg. Barcelona */
char *equipas[2];
int score[2];
} jogo2;
int main() {
printf("sizeof jogo %d\n",sizeof(jogo));
printf("sizeof jogo2 %d\n",sizeof(jogo2));
return 0;
}
As you could see jogo has a pointer size and jogo2 has the size of your struct.
More, there are various problems in your code. Everything is briefly commented directly in the code. Do not hesitate to ask questions.
#include<stdlib.h>
#include<stdio.h>
#include <string.h>
#define MAX_CHARS 1024
#define MAX_SIZE 5
int line = 1;
// static int size = MAX_SIZE; // Not useful. It is the same than MAX_SIZE
// int i = 0; this variable is not really used
int size_until = 0;
typedef struct jogo
{
// int ident; Never used
char nome[MAX_CHARS];
char equipas[2][1024]; // equipas is an array of two strings. If you use char *equipas[2], you will have to alloc memory for each string
int score[2];
} jogo; // * has been removed
jogo **sistema_jog; //sistema_jog is an array of pointer to jogo struct. You allocate it after.
// you could also have an array of jogo struct but it would need more modifications in your code.
// I suppose the confusion is here. To train, you could try to do : jogo * sistema_jog and to modify what it is needed in your code.
void a(char nome[],char team1[],char team2[],int score1,int score2);
int team_not_in(char team1[],char team2[]);
int nome_in(char nome[]);
void cria_jogo(jogo* s,char nome[],char equipa1[],char equipa2[],int score1,int score2); // *: s is a pointer to jogo struct. See comment on sistema_jog declaration
int main() {
char c; char nome_jg[MAX_CHARS]; char eq1[MAX_CHARS]; char eq2[MAX_CHARS]; int pont1; int pont2;
sistema_jog = (jogo**) calloc(MAX_SIZE,sizeof(jogo*)); // Each element of sistema_jog is a pointer to a jogo struct
while ((c = getchar())!= 'x') {
switch (c)
{
case 'a':
{
scanf("%1023[^:\n]:%1023[^:\n]:%1023[^:\n]:%d:%d",nome_jg,eq1,eq2,&pont1,&pont2); // be carefull, see % and 1023 in the third field of your code
// i++; not used elsewhere
a(nome_jg,eq1,eq2,pont1,pont2);
break;
}
}
}
// Only to check
for (int i=0; i<size_until;i++)
printf ("%s:%s:%s:%d:%d\n",
sistema_jog[i]->nome,
sistema_jog[i]->equipas[0],
sistema_jog[i]->equipas[1],
sistema_jog[i]->score[0],
sistema_jog[i]->score[1]);
return 0;
}
int nome_in(char nome[])
{
int i;
for(i=0; i < size_until; i++) // size_until : You have to check only elements that exist either you have less or more elements than size (static int = MAX_SIZE)
{
if (strcmp(sistema_jog[i]->nome,nome) == 0)
return 1;
}
return 0;
}
int team_not_in(char team1[],char team2[])
{
int i;
for (i=0;i<size_until;i++) // size_until : Idem as above
{
if((strcmp(sistema_jog[i]->equipas[0],team1) != 0) || (strcmp(sistema_jog[i]->equipas[1],team2) != 0))
return 1;
}
return 0;
}
void cria_jogo(jogo* s,char nome[],char equipa1[],char equipa2[],int score1,int score2) // * : s is a pointer to jogo struct
{
strcpy(s->nome,nome);
strcpy(s->equipas[0],equipa1);
strcpy(s->equipas[1],equipa2);
s->score[0] = score1;
s->score[1] = score2;
}
void a(char nome[],char team1[],char team2[],int score1,int score2)
{
int NL = line;
if (nome_in(nome) == 1)
printf("%d Jogo existente.",NL);
/* else if (team_not_in(team1,team2) == 0)
{
printf("%d Equipa existente.",NL);
} */ // I do not understand the objective of this test. So, I commented it. But it is not the question
else
{
jogo* novo_jogo = (jogo*) malloc(sizeof(jogo));
cria_jogo(novo_jogo,nome,team1,team2,score1,score2);
if (size_until < MAX_SIZE) // = has been removed. Index of array goes from 0 to size of array-1
{
sistema_jog[size_until] = novo_jogo;
size_until++;
}
else
{
sistema_jog = (jogo**) realloc(sistema_jog, sizeof(jogo**)*(size_until+1)); // *: see comment on sistema_jog declaration, +1: array index goes from 0 to size-1
// Remark : It is not efficient to realloc one by one. It would better to realloc MAX_SIZE by MAX_SIZE. You could try to do it
sistema_jog[size_until] = novo_jogo;
size_until++;
}
}
}

Is it possible to only send one variable from a struct if that struct exists as an array?

I apologise if this seems simple, I'm still learning and I'm new to C.
I have this as my struct:
struct Game{
char id;
char name[50];
char genre[20];
char platform[15];
char company[30];
float price;
int quantity = 10;
};
And this declared as a struct array:
struct Game gList[30];
I have a function where I'm passing all of 'gList' to search through values in the gList[i].name variables.
So my question is, is it possible to send only the gList[i].name part of the struct to the function as a parameter?(ie All the 30 name values only).
No.
But you could make an array of pointers that point to the name field and pass it to the function:
char* ptr[30];
for(int i = 0; i < 30; i++)
ptr[i] = gList[i].name;
func(ptr);
No you can't. However, you can pass iterators to functions just fine. Typical pattern:
struct context { struct Game *gList; int nList; int i; }
char *iter_names(void *baton)
{
struct context *ptr = baton;
if (ptr->i == ptr->nList) return NULL;
return ptr->gList[ptr->i++].name;
}
void wants_name_array(char (*nextname)(void *), void *baton)
{
while (char *name = nextname(baton))
{
printf("%s\n", name);
/* and whatever else you are doing */
}
}
/* ... */
struct context baton = { gList, 30, 0 };
wants_name_array(iter_names, baton);
Yeah it looks kinda bad. Thankfully, gcc has an extension that makes this much better.
void wants_name_array(char (*nextname)())
{
while (char *name = nextname())
{
printf("%s\n", name);
/* and whatever else you are doing */
}
}
/* ... */
{
int i = 0;
char *nextname()
{
if (i == 30) return NULL;
return gList[i++].name;
}
wants_name_array(nextname);
}
When using this particular gcc extension, never ever return nested functions. Undefined behavior.

Using a string as a variable part of structures's name in a function in plain C

I've encountered a problem trying to reduce the size of my code. What I was trying to do was passing either name or color to function writedata so that I wouldn't have to write it twice for each case.
typedef struct Pet{
char* name;
char* color;
} pet;
void writedata(pet *Pet, char string[], const char field[]){
gets(string);
Pet->field= (char*)malloc(strlen(string)+1);//I wanted it to be treated like Pet->name
strcpy(Pet->field, string);
}
The call of the function:
writedata(Pet, string, name);
I'm quite sure I got something wrong.
update: the whole code http://ideone.com/Y7L8Hu
update2: I tried to implement it using offset according to BLUEPIXY's advice but it seems I misunderstand manipulations with fields using their addresses... I believe the problem could be that the fields aren't initialized in the first place, but then again, my aim is to initialize them.
typedef struct Pet{
char* name;
int legs;
char* color;
} pet;
void writedata(pet *Pet, size_t FIELD){
char string[50];
gets(string);
(char*)Pet+offsetof(struct Pet, FIELD) = (char*)malloc(strlen(string)+1);//I wanted it to be treated like Pet->name
strcpy((char*)Pet+FIELD, string);
}
That's not how C works. However, I think using string comparison can achieve what you need:
if (strcmp(field, "name") == 0)
{
Pet->name = ...
}
else if (strcmp(field, "color") == 0)
{
Pet->color = ...
}
And call it with a string literal:
writedata(Pet, string, "name");
Using enum is also an option.
BTW, don't use gets, it's dangerous, use fgets instead.
use macro function sample.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define writedata(var, buffer, field) \
do {\
int len = strlen(buffer);\
var->field = (char*)malloc(len + 1);\
memcpy(var->field, buffer, len+1);\
}while(0)
typedef struct Pet{
char* name;
int legs;
char* color;
char* voice;
} pet;
void addpet(pet* Pet, int *TotalLegs){//Can not be used reference(&) in C
char buff[50];
int len;
puts("Input name");
scanf("%49[^\n]", buff);
writedata(Pet, buff, name);
puts("How many legs?");
scanf("%d%*c", &Pet->legs);
puts("What does it say?");
scanf("%49[^\n]%*c", buff);
writedata(Pet, buff, voice);
puts("_____\n");
*TotalLegs += Pet->legs;
}
int main(){
int TotalLegs = 0;
pet* Pet1 = (pet*)malloc(sizeof(pet));
addpet(Pet1, &TotalLegs);
pet* Pet2 = (pet*)malloc(sizeof(pet));
addpet(Pet2, &TotalLegs);
pet* Pet3 = (pet*)malloc(sizeof(pet));
addpet(Pet3, &TotalLegs);
//printf("%s\n", Pet1->name);
//printf("%s\n", Pet1->voice);
printf("The animals have %d legs\n", TotalLegs);
free(Pet1);free(Pet2);free(Pet3);
return 0;
}
A lot of things are wonky in your code.
What you wish to do can be achieved but it takes different type of code than you'd want to write.
What you really want to do is simply create a function that fills in a name and a color.
So here is the simplest way to do it:
typedef struct pet {
char *name;
char *color;
} pet_t;
pet_t * new_pet(const char *name, const char *color)
{
pet_t *p;
p = malloc(sizeof(pet_t));
if ( p == NULL )
return NULL;
p->name = strdup(name); /* allocate space and copy string */
p->color = strdup(color); /* allocate spance and copy string */
return p;
}
void delete_pet(pet_t *p)
{
if ( p-> name )
free(p);
if ( p->color)
free(color);
if ( p )
free(p);
}
int main() {
pet_t *p;
p = new_pet("Harry", "brown");
printf("%s is a %s pet\n", p->name, p->color);
delete_pet(p);
return 0;
}

Check Structure, add items if not already in structure. C

I'm trying to do some practice programming and I've come to a, for me, a difficult problem.
The problem is I'm supposed to write a program the will take the make and model of a car that was "entered" and place it in the structure, if the make an model are not there, otherwise it does nothing.
This is what I have so far, and I keep getting errors:
#include <stdio.h>
#include <string.h>
void addCar(struct car u, int* count, char *make[], char *model[]);
struct car { char make[30]; char model[30]; };
int main(void)
{
struct car unique[10] = {{"Ford", "Explorer"}, {"Honda", "Civic"},
{"Honda", "Accord"}, {"Chevy", "Malibu"}};
int i, count = 4;
addCar(unique, &count, "Ford", "Mustang");
}
void addCar(struct car u, int* count, char *make[], char *model[])
{
}
The line that says addCar(unique, &count,... it's saying "Argument type 'struct car' is incomplete" and the last line says "conflicting types for addCar"
Could you all give me a few pointers, please?
EDIT:
Okay, here is what my code is now, but I still can't get it to work. Any other suggestions would be appreciated!
#include <stdio.h>
#include <string.h>
struct car { char make[30]; char model[30]; };
void addCar(struct car *u, int *count, char *make, char *model);
int main(void)
{
struct car unique[10] = {{"Ford", "Explorer"}, {"Honda", "Civic"},
{"Honda", "Accord"}, {"Chevy", "Malibu"}};
int i, count = 4;
printf("%s", unique[0].make);
addCar(unique, &count, "Ford", "Mustang");
}
void addCar(struct car *u, int *count, char *make, char *model)
{
int i = 0;
for (i; i < *count; i++)
{
if ((u[i].make != make) && (u[i].model != model))
{
strcpy(u->make, make);
strcpy(u->model, model);
count++;
}
}
for (i = 0; i < *count; i++)
printf("%s, %s", u[i].make, u[i].model);
}
struct car unique[10] = {{"Ford", "Explorer"}, {"Honda", "Civic"},
{"Honda", "Accord"}, {"Chevy", "Malibu"}};
This is an array of struct car, therefore, you need to declare your addCar function as follow
void addCar(struct car *u, int *count, char *make, char *model)
*make and *model represent 2 strings. You have a mistake when you have char *make[], which declares an array of string.
Your function prototype for addCar is defined and uses 'struct car' before you define 'struct car'. Try moving the structure definition above the prototype for addCar.
Here are a few things that I figured out when looking at your code.
In this case, I think it's best if you use while loop rather than for loop.
Secondly, if you want to make sure that the car you want to add does not exist in the list, I suggest you use this
while (i < *size) {
if ((u[i].make == make) && (u[i].model == model)) { break; } // check if the car is already in the list
i++;
}
It checks the whole list for the existence of an element with the same make and model.
Here is the code I modified from yours. I hope it helps you.
#include <stdio.h>
#include <string.h>
struct car { char make[30]; char model[30]; };
void addCar(struct car *u, int *count, char *make, char *model);
int main(void)
{
struct car unique[10] = {{"Ford", "Explorer"}, {"Honda", "Civic"},
{"Honda", "Accord"}, {"Chevy", "Malibu"}};
int i, count = 4;
addCar(unique, &count, "Ford", "Mustang");
for (i = 0; i < count; i++) {
printf("%s, %s\n", unique[i].make, unique[i].model);
}
}
void addCar(struct car *u, int *size, char *make, char *model)
{
int i = 0;
while (i < *size) {
if ((u[i].make == make) && (u[i].model == model)) { break; } // check if the car is already in the list
i++;
}
if (i == *size) { // car found
struct car c;
strcpy(c.make, make);
strcpy(c.model, model);
u[i] = c;
(*size)++;
}
}

Resources