I am really newbie in C and I want create a program that reads two input files which are only include strings. I have created for its related file's strings. I have dealing with some problem and I couldn't figure out, there is some segmentation fault in there. (asked by-ua)
Here is my code:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdbool.h>
typedef struct linked_list {
char my_data[256];
struct linked_list *next_it;
} node_t;
int main(int argc, char *argv[]) {
/*
if(argc != 4) {
fprintf(stderr, "Requiring 2 input 1 output file name to start!\n");
exit(EXIT_FAILURE);
}*/
FILE *my_s;
FILE *my_f;
// FILE *my_o;
bool mybool = true;
int my_ch; // our char to read
char my_buffer[256];
bool check_all = true;
node_t *set_a = malloc(sizeof(node_t));
node_t *set_b = malloc(sizeof(node_t));
my_f = fopen(argv[1], "r"); // first textfile to read
my_s = fopen(argv[2], "r"); // second textfile to read
if (my_f != NULL && my_s != NULL) {
while (fgetc(my_f) != EOF && mybool != false && check_all != false) {
my_ch = fgetc(my_f);
int i = 0;
while (my_ch >= 0) {
my_buffer[i++] = my_ch;
my_ch = fgetc(my_f);
}
strcpy(set_a->my_data, my_buffer);
if (feof(my_f)) {
mybool = false;
} else {
set_a->next_it = malloc(sizeof(node_t));
set_a = set_a->next_it;
}
}
mybool = false;
printf("First File Copy Done!\n");
while (fgetc(my_s) != EOF && mybool != true && check_all != false) {
my_ch = fgetc(my_s);
int i = 0;
while (my_ch >= 0) {
my_buffer[i++] = my_ch;
my_ch = fgetc(my_s);
}
strcpy(set_b->my_data, my_buffer);
if (feof(my_s)) {
check_all = false;
} else {
set_b->next_it = malloc(sizeof(node_t));
set_b = set_b->next_it;
}
}
printf("Second File Copy Done!\n");
} else {
fprintf(stderr, "Cannot read from %s and %s\n", argv[1], argv[2]);
}
while (set_a != NULL) {
int j = 0;
printf("No: %d, Var: %s",j++, set_a->my_data);
node_t *set_c = set_a;
set_a = set_a->next_it;
free(set_c);
}
while (set_b != NULL) {
int j = 0;
printf("No: %d, Var: %s",j++, set_b->my_data);
node_t *set_c = set_b;
set_b = set_b->next_it;
free(set_c);
}
return 0;
}
You are not pointing the tail of the two linked lists to 'NULL' after reaching the end of file and you are not maitaining the heads of each linked list. You change the head each time reading a string. So at final stage 'set_a' and 'set_b' become the last node without a NULL tail
Your code has several problems:
NULL
. feof(my_s)
, but this function does not do what you think it does. It is much better to check is fgetc()
returns EOF
, but store the byte it read. my
or my_
, this is not helping, just use the short names, they are not supposed to designate anything global anyway. set_a
and set_b
to point to the next node, there is just no way to find the head of the lists anymore. j
to 0
in each iteration of the print and free loop, all nodes will print with number 0
. Here is an improved version:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdbool.h>
typedef struct linked_list {
char *data;
struct linked_list *next;
} node_t;
node_t *load_lines(const char *filename) {
node_t *head = NULL;
FILE *fp = fopen(filename, "r");
if (fp != NULL) {
char buffer[256];
size_t i = 0;
int c;
node_t **tailp = &head;
for (;;) {
c = fgetc(fp);
if (c != EOF && c != '\n') {
if (i < sizeof(buffer) - 1) {
buffer[i++] = c;
}
continue;
}
if (i > 0) {
buffer[i] = '\0';
/* allocate a new node */
*tailp = malloc(sizeof(**tailp));
(*tailp)->next = NULL;
(*tailp)->data = strdup(buffer);
tailp = &(*tailp)->next;
i = 0;
}
if (c == EOF) {
break;
}
}
fclose(fp);
}
return head;
}
void print_word(node_t *np) {
int j = 0;
while (np != NULL) {
printf("No: %d, Var: %s", j++, np->data);
np = np->next;
}
}
void free_words(node_t *np) {
while (np != NULL) {
node_t *next = np->next;
free(np->data);
free(np);
np = next;
}
}
int main(int argc, char *argv[]) {
/*
if (argc != 4) {
fprintf(stderr, "Requiring 2 input 1 output file name to start!\n");
exit(EXIT_FAILURE);
}*/
node_t *set_a, *set_b;
if ((set_a = load_words(argv[1])) != NULL) {
printf("First File Copy Done!\n");
}
if ((set_b = load_words(argv[2])) != NULL) {
printf("Second File Copy Done!\n");
}
if (!set_a && !set_b) {
fprintf(stderr, "Cannot read from %s and %s\n", argv[1], argv[2]);
}
print_words(set_a);
free_words(set_a);
print_words(set_b);
free_words(set_b);
return 0;
}
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.