I'm trying to read in a text file, say input.txt, into an array of structs to then print out (and free memory of course). My C coding is a bit scratchy though, and I'm looking for help.
Input.txt contains lines of information about a single person. I want to read in the people, sort by name and print out in sorted order. Before I can do this, I'm just trying to create an array of people, allocate memory to each person, copy in the details from the text file, and then print them out finally. It's not even getting to the print out, as you can see it gives a segmentation fault:
I'm using the following:
gcc -Wall -O2 -o program filename.c
and getting this
Segmentation fault: 11
input.txt contents:
Joan 0212672938 [email protected]
John 0365242939 [email protected]
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
struct person {
char *name;
char *phone;
char *email;
};
int main(void) {
int i;
int peopleSize = 0;
char * pch;
FILE *f = fopen("input.txt", "r");
if (f == NULL) return EXIT_FAILURE;
struct person** people = malloc(100 * (sizeof (people[0])));
/* Create 100 people */
char *nameTmp = malloc(30 * sizeof nameTmp[0]);
char *phoneTmp = malloc(30 * sizeof phoneTmp[0]);
char *emailTmp = malloc(30 * sizeof emailTmp[0]);
/* Open the file for reading */
char *line_buf = NULL;
size_t line_buf_size = 0;
int line_count = 0;
ssize_t line_size;
/* Get the first line of the file. */
line_size = getline(&line_buf, &line_buf_size, f);
while (line_size >= 1) {
line_count += 1;
people[line_count-1] = malloc(sizeof (people[line_count-1]));
/* if fgets returns an empty space or new line, no more people to add, break loop */
/* Within str, use strtok to divide strings up into name, phone and email */
strcpy(pch, line_buf);
pch = strtok (pch, " ");
strcpy(nameTmp, pch);
printf("%s\n", nameTmp);
if (pch != NULL) {
pch = strtok (NULL, " ");
strcpy(phoneTmp, pch);
}
if (pch != NULL) {
pch = strtok (NULL, " ");
strcpy(emailTmp, pch);
}
/* Allocate enough memory to person->name and person->phone and person->email as required */
people[line_count-1]->name = malloc((strlen(nameTmp) + 1) * sizeof (people[line_count-1]->name[0]));
people[line_count-1]->phone = malloc((strlen(phoneTmp) + 1) * sizeof (people[line_count-1]->phone[0]));
people[line_count-1]->email = malloc((strlen(emailTmp) + 1) * sizeof (people[line_count-1]->email[0]));
/* Now copy values from temporary variables into actual person */
strcpy(people[line_count-1]->name, nameTmp);
strcpy(people[line_count-1]->phone, phoneTmp);
strcpy(people[line_count-1]->email, emailTmp);
/* Get the next line */
line_size = getline(&line_buf, &line_buf_size, f);
}
peopleSize = line_count;
/* Printing all the people out */
for (i = 0; i < peopleSize; i++) {
printf("%s\t", people[i]->name);
printf("%s\t", people[i]->phone);
printf("%s", people[i]->email);
printf("\n");
}
/* Freeing all of the memory */
for (i = 0; i < peopleSize; i++) {
free(people[i]->email);
free(people[i]->phone);
free(people[i]->name);
free(people[i]);
}
free(people);
return EXIT_SUCCESS;
}
pchis not initialized but you are trying tostrcpy()to it. Have you checked the crash using any debugger likegdb? Also instead ofpeople[line_count-1] = malloc(sizeof (people[line_count-1]));trypeople[line_count-1] = malloc(sizeof (struct person));