简体   繁体   English

读取文件字符串

[英]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. 我真的是C语言的新手,我想创建一个程序来读取两个仅包含字符串的输入文件。 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) (由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. 到达文件末尾后,您没有将两个链接列表的末尾指向“ NULL”,也没有保留每个链接列表的头。 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 因此,在最后阶段,“ set_a”和“ set_b”成为没有NULL尾的最后一个节点

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 . 无法在此节点中进行任何测试...为什么不将空列表初始化为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. 稍后,您检查feof(my_s) ,但此功能无法执行您认为的功能。 It is much better to check is fgetc() returns EOF , but store the byte it read. 最好检查一下fgetc()返回EOF ,但存储它读取的字节。
  • 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. 为什么用mymy_开头每个局部变量名,这my_ ,只使用短名称,无论如何它们都不应该指定全局名称。
  • 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. 你不是一个指针保持到每个列表的头,你设置set_aset_b指向下一个节点,就是没有办法再找到列表的头部。
  • You reset j to 0 in each iteration of the print and free loop, all nodes will print with number 0 . 您在打印和自由循环的每次迭代中将j重置为0 ,所有节点将以数字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;
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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