To start off this was a homework assignment, keyword was, past due now and unfortunately submitted as is. Now I'm posting for my own learning process as I am continuing to have trouble understanding what I am doing wrong. I have tried searching for this specific issue but nothing seems to fit the bill, some come close but separate problem with different answers that don't particularly pertain to the exact problem I'm having.
What I have is a .txt file of words separated by '#'. The assignment was to read the input into dynamic arrays to allow the addition and deletion of words to be used in a MadLib sentence.
article
the
a
one
some
any
#
noun
boy
girl
dog
#
verb
drove
jumped
walked
skipped
#
preposition
to
from
over
under
on
#
What I have done is open the file, read the contents, determine how many items per section, and then I have what I believe to be correct is allocate memory for a dynamic array based on the results of nItems. I have then rewind() the file and began to copy the contents line by line into a separate variable named temp. Then this is where it gets a little muddy, although I thought I was doing this correctly, perhaps my calloc isn't quite right, I'm not sure, but I thought the items were then copied into the appropriate array through for and if statements. All that seems to work fine(without fault) but when I attempt to print out the array I get a Segmentation Fault.
I'm not sure in what part I am messing up. If at all possible I'd like some more information for a better understanding of all this so I can learn and improve and hopefully not make the same mistakes. Pointers in general seem to give me the most trouble, I get their purpose but when it comes to implementation its a hit or miss for me.
Here's some of the code from my one function.
void fillArray(char * article, char * noun, char * verb, char * prep, FILE * fin)
{
int row = 0;
row = getRows(fin, row);
article = (char*)calloc(row, sizeof(char*));
row = getRows(fin, row);
noun = (char*)calloc(row, sizeof(char*));
row = getRows(fin, row);
verb = (char*)calloc(row, sizeof(char*));
row = getRows(fin, row);
prep = (char*)calloc(row, sizeof(char*));
rewind(fin);
arrFill(article, fin);
arrFill(noun, fin);
arrFill(verb, fin);
arrFill(prep, fin);
}
void arrFill(char * arr, FILE * fin)
{
int i, size;
size = sizeof(arr);
char temp[100];
fgets(temp, 100, fin);
for(i = 0; i < size; i ++)
{
fgets(temp, 100, fin);
stripChar(temp);
if(*temp != '#')
strcpy(&arr[i], temp);
}
}
I appreciate any help and constructive comments given.
There are a couple of problems with your code. The first is that when you allocate memory for article
you allocate memory for row
characters, not row
strings. You then don't reset the row counter so you will allocate the number of articles and the number of nouns for noun
(still as a number of single characters and not strings).
The above leads to other problems for example when you do
strcpy(&article[i], temp);
you try to copy a string into a character (i.e. not a pointer). This will cause undefined behavior.
Another problem is that e.g. sizeof(article)
returns the size of the pointer, and not what it points to.
A fourth problem is that you pass the pointers by value, i.e. when you call the function the pointers you pass as arguments are copied, and you overwrite only the copies when you allocate the memory. You need to pass the pointers by reference (i.e. as pointers to the pointers).