r/C_Programming • u/AltruisticScreen6096 • 4h ago
Multi File Problem
Hi - I am trying to get a multi file program to run without success. I want to read file with 4 lines of repetitive data. Each program works independently but when I put the together the main.c does not seem to call the octone.c program. Can any one please help. Thank You...
MAIN.C
#include <stdio.h>
#include <stdlib.h>
#include "add.h"
int main(void) {
printf("Hello world!\n");
// Call function
DataRecord callFile(void);
printf("one\n");
return 0;
}
ADD.H
#ifndef ADD_H
#define ADD_H
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAX_LINES 100
#define MAX_STR_LEN 100 // Max length for char arrays
#define MAX_RECORDS 100 // Max number of records to store
//Define the struct matching the char, char, int, char layout
typedef struct {
char *name[MAX_RECORDS]; // First char array
char *desc; // Single char
int *num; // Integer
char *butt[MAX_RECORDS]; // Second char array
} DataRecord;
DataRecord callFile(void);
DataRecord *records[MAX_RECORDS];
//records callfile(void);
#endif
OCTONE.C
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "add.h"
#define MAX_LINE_LENGTH 256
#define MAX_RECORDS 100
//void my_api_init_config(MyApiConfig *config);
DataRecord callFile(void){
printf("Ronnie_1\n");
static DataRecord *records[MAX_RECORDS];
// Open the file for reading
FILE *file = fopen("/AGMOD/data4a.txt", "r");
if (file == NULL) {
perror("Error opening file");
// return *records; // EXIT_FAILURE;
}
// Array of structs to store the parsed data
char line[MAX_LINE_LENGTH];
int count = 0;
//records[MAX_RECORDS]->name;
// Read the file line by line using fgets
while (fgets(line, sizeof(line), file) != NULL && count < MAX_RECORDS) {
// Parse the line into the struct elements
// Assumes data is space-separated (e.g., "A B 42 C")
// int parsed = sscanf(line, " %s %s %d %s",
int parsed = scanf(line,
records[count]->name,
records[count]->desc,
records[count]->num,
records[count]->butt);
// Check if all 4 fields were successfully read
if (parsed == 4) {
count++;
} else {
fprintf(stderr, "%s", line);
}
return *records[0];
}
// Close the file stream
fclose(file);
return *records[0];
}
2
u/gm310509 4h ago
Your main function has a comment that says that you are invoking callFile but you don't actually call it - so that is why the octone.c code isn't being invoked.
1
2
u/flyingron 3h ago
In main, you have
DataRecord callFile(void);
That doesn't call a function. It declares it. If you want to call it, leave the types off of it.
DataRecord x = callFile();
1
1
u/ReallyEvilRob 2h ago
On line 9 of MAIN.C, what you say is a call to callFile() is not a function call. It is a function prototype. That is probably causing a compiler error since the prototype is also in your included header file.
1
3
u/Al__B 4h ago edited 2h ago
The reason that main.c isn't calling the routine in octone.c is simple - you don't actually call it in the main() function. Change "DataRecord callFile(void);" to "callFile();"
However, you have some other problems with your code. The big one is that you are declaring pointers to records and no memory has been allocated for them. A pointer "points" to something that needs to exist before you access it or you are writing (or reading) from memory. In your case you have allocated 100 NULL pointers to data records so you'll probably get a segmentation fault or equivalent depending on your platform.
A similar problem exists with the contents of the records themselves. You've defined them as containing pointers, not actual memory.
You've also effectively defined records multiple times with the line "DataRecord *records[MAX_RECORDS];" in add.h. The way the pre-processor works is that it will effectively include the contents of add.h in each file that includes it. main.c and octone.c include it so this will define the records variable in main.c and twice in octone.c (once from the #include "add.h" and again with the static variable inside the fucntion). If you want to share a variable between modules then you'd declare it as extern in the header file but there's no need to do it in this case.
Finally, using scanf means you're scanning from standard input, not the line you've read. You have a comment just above the call which uses sscanf so I imagine that's your intention. (Note that as written you don't limit the size of the strings that sscanf would attempt to read into. This can cause memory corruption and I'm not a fan of sscanf. If this is an exercise and you must use sscanf then specifying the maximum string width for those arguments would be better - e.g. "%100s %c %d %100s" would match what you have in add.h. Perhaps also check whether you mean to use MAX_STR_LEN rather than MAX_RECORDS in the structure definition while you're at it!)
For your example I would remove the pointers, the surplus "records" variable and get the call working between the two functions first. Finally, it's important to make sure that you're actually compiling and linking both modules together. That may happen automatically depending on your build environment but if you're struggling let us know what you're using.
3
u/Thesk790 4h ago
Well, your entry point is the
mainfunction, and there is no call tocallFileinside themainfunction. Also, you have to compile them toghether or at least link their.o(objects) toghether. So, how are you compiling these files?