This is for a phonebook program. It reads data from a CSV but can also take input from the terminal (e.g. through scanf). It loads the csv info into a struct linked-list. We are told to use a global variable that should be the the head pointer (the type is the struct). Basically I have three files: main.c phone.c helper.c. Main.c runs the menu, asks for user input, and calls functions according to the option selected. All the functions related to those options are in the file phone.c (e.g. add, delete, list, find, etc). Any helper functions are in helper.c.
We have to use header files and a Makefile, and though I have experience with those I have run into an issue I don't know how to solve: how do I make the head variable global for multiple functions using header files? Additionally, how do I compile this properly using objects (.o files)?
I know using global variables isn't good practice necessarily but it's a requirement for this project.
Approach 1: I tried declaring the struct in helper.h and defining it in helper.c. If I #include "helper.h"
into phone.c, I can access the variable from there. But then I need to #include "phone.h"
into main.c to acess the functions, but that alone doesnt let me access *HEAD, so I have to #include "helper.h"
into main.c as well which gives me a "multiple definitions" compilation error.
Approach 2: I declared the struct in phone.h and defined it in phone.c. But this means that I have to #include "phone.h"
in helper.c AND #include "helper.h"
in phone.c (to use its functions). And then I have to include both in main.c and it just becomes a big mess of multiple definition and scope errors.
We were told off-record to declare the struct in phone.h and define it in phone.c. But then how can I acess the struct data type from insde helper.h? and if I need to #include "phone.h"
into helper.c, can I also #include "helper.h"
into phone.c? Where does the extern declaration go?
Note: I found a way of getting it to compile. Declare struct in helper.h. #include "helper.h"
in phone.h. extern struct PHONE_RECORD *HEAD
in phone.h. #include "phone.c"
in phone.c. However, when I run the program I get a segfault. From what I can tell, main.c has access to the *HEAD variable but phone.c doesn't.
Here's some of the code:
main.c
#include "phone.h"
int main(void) {
//calls functions from phone.c and helper.c
phone.c
#include "phone.h"
struct PHONE_RECORD *HEAD;
//a bunch of functions that call functions from helper.c
phone.h
#ifndef PHONE_H
# define PHONE_H
#include "helper.h"
#define FILENAME "./phonebook.csv"
#define BUFFER 1024
extern struct PHONE_RECORD *HEAD;
//function declarations
#endif
helper.c
#include "helper.h"
//functions called by main.c and phone.c
//I can't access *HEAD from here, it needs to be passed as a parameter
helper.h
#ifndef HELPER_H
# define HELPER_H
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
struct PHONE_RECORD {
char name[50];
char birthdate[12];
char phone[15];
};
//function declarations
#endif
----SOLUTION----
In case anyone stumbles upon this in the future, I asked chat gpt and it solved the issue. Basically I had to:
- Declare the struct in phone.h
- Extern the *HEAD variable in phone.h
extern struct PHONE_RECORD *HEAD;
- Define the *HEAD variable in phone.c
struct PHONE_RECORD *HEAD = NULL;
#include "phone.h"
and#include "helper.h"
in phone.c#include "phone.h"
in helper.c- Have only function declarations in helper.c
#include "phone.h"
and#include "helper.h"
in main.c
And when compiling:
Compile each file individually using gcc -c <file>
Link all the files with gcc main.o phone.o helper.o -o <program_name>
Now I can access *HEAD from all functions and no longer get a segfault.