Trying to read multiple line from file to store them in a structure made up of the string elements, however when I run the program it simply crashes and I haven't the faintest idea why.
function in question:
Hashtbl* loadfromfile(Hashtbl* hashtbl, char *path){
int i = 0;
char line[100];
char* string[40];
FILE *f = fopen(path, "r");
if(f == NULL){
printf("FILE NO FOUND!");
}else{
while(fgets(line, sizeof(line), f)!=NULL){
strcpy(string[i],line);
i++;
}
fclose(f);
for(i = 0; i<(SIZE*2); i++){
strcpy(hashtbl[i].subscript, string[i]);
i++;
}
for(i = 1; i<(SIZE*2); i++){
strcpy(hashtbl[i].value, string[i]);
i++;
}
return hashtbl;
}
}
main.c:
#include <stdio.h>
#include <stdlib.h>
#include "hashtable.h"
int main() {
Hashtbl* numbers;
numbers = init_hashtbl(); //init_hashtable initialises numbers
loadfromfile(numbers, "test.txt");
for(int i = 0; i<SIZE; i++) {
printf("%s1", numbers[i].subscript);
printf("%s2\n", numbers[i].value);
}
}
Hashtable structure:
typedef struct Hashtbls{
char *subscript;
char *value;
} Hashtbl;
init_hasthable function:
Hashtbl* init_hashtbl(){
Hashtbl* hashtbl;
hashtbl = calloc(SIZE, sizeof(Hashtbl));
for(int i = 0; i<SIZE; i++){
hashtbl[i].subscript = "ZERO";
hashtbl[i].value = "ZERO";
}
return hashtbl;
}
You have quite a few problems here:
If the file cannot be opened, then you cannot continue. Also the message might be printed way later, use
printf("FILE NOT FOUND!\n");
instead.string
is an array of uninitialized pointers, you cannot write anything there. You should doAlso you are not checking whether you read more than 40 lines. I did that with the the last
if
.sizeof array / sizeof *array
returns the number of elements that an array can hold. Note that this only works for arrays, not pointers, since in generalsizeof array != sizeof pointer
. Also don't forget to free the allocated memory afterwards.Are the
subscript
andvalue
parameters here initialized in some way? Check yourinit_hashtbl()
.EDIT
Now that you posted
init_hashtbl
:You are initializing
subscript
andvalue
with string literals, they are pointing to read-only memory location,strcpy
is going to fail. You have to either allocate memory withmalloc
or change your structure with arrays.Option 1
Keep the structure, change
init_hashtbl
You should always check the return value of
malloc
/calloc
. Also the problem here is that if you want to copy a string that is longer thanSOME_MAXIMAL_LENGTH
, you are going to have a buffer overflow. So you should use realloc in the reading routine:If you don't want to deal with
realloc
here, you have to make sure, that nostring[i]
is longer thanSOME_MAXIMAL_LENGTH
.Option 2
Change you structure and init:
Then in
loadfromfile
you don't have to deal with therealloc
as shown above, you can keep your code. However, you have to check that nostring[i]
is longer thanSOME_MAXIMAL_LENGTH - 1
, otherwise buffer overflow.One last thing,
fgets
reads a whole line, assuming that the length of the line is lesser thansizeof line
, the newline character will be added to the line. You most likely don't want to have that. One way of getting rid of the newline is: