简体   繁体   中英

Reading strings of files

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:

  • You initialize your list with an uninitialized first node. There is no way to test anything in this node... Why not initialize an empty list as NULL .
  • You test for end of file by reading the next byte from each file, but you do not store this byte... so it gets lost. Later you check for 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.
  • Why do you start every local variable name with my or my_ , this is not helping, just use the short names, they are not supposed to designate anything global anyway.
  • You do not keep a pointer to the head of each list, you set set_a and set_b to point to the next node, there is just no way to find the head of the lists anymore.
  • You reset j to 0 in each iteration of the print and free loop, all nodes will print with number 0 .
  • You should use functions to load, print and free the lists, to avoid repeating the same code twice.

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM