如何解决将错误插入链接列表的问题。从文件流

时间:2019-05-05 03:22:08

标签: c linked-list

我正在尝试将值插入到链表中,但是仍然使程序崩溃。我知道我做错了事,只是不确定要做什么,在花了8个小时尝试了不同的方法之后,我准备寻求帮助。

我尝试了许多不同的方法来使其正常工作。有时候我似乎能够存储和连接节点,但是当我尝试打印时,它要么只打印第一个节点,要么什么都不打印。

typedef struct histogram {
    char *word;
    int count;
    struct histogram *next;
} List;

static List *createWord(char word[]) {
    char *wordPtr = word;

    List *node = (List *)malloc(sizeof(List));
    node->word = wordPtr;
    node->count = 1;
    return node;
} 

static void insertAtTail(List **head, List *node) {
    List *previous = *head;

    if (*head == NULL) {
        *head = node;
    } else {
        while (previous->next != NULL) { // error location
            previous = previous->next;
        }
        previous->next = node;
        node->next = NULL;
    }
}

void readMain(char *fileName) {
    // responsible for read operatons and list storage.
    // Counts total words and uniques than stores words in linked list.

    char word[100];
    char *wordArray[1500] = { NULL };

    static int noOfWords = 0;
    static int uniqueWords = 0;

    List *head = NULL;
    List *temp = NULL;

    fileRead(inputFile);

    while (fscanf(inputFile, "%s", word) == 1) {
        if (determineIfWord(word) == 0) {
            noOfWords++;
            temp = createWord(word);
            insertAtTail(&head, temp); // error occurs here

            if (!compareWords(wordArray, word, uniqueWords)) {
                wordArray[uniqueWords] = calloc(strlen(word) + 1,
                                                sizeof(char));

                if (wordArray[uniqueWords] == NULL) {
                    printf("calloc failed to allocate memory\n");
                    exit(0);
                }
                strcpy(wordArray[uniqueWords], word);
                uniqueWords++; 
            }
        }

    fclose(inputFile);

    freeArray(wordArray, uniqueWords);

    noOfWords -= 1;
    printf("\n%s processed: %i unique words found.\n\n", fileName, uniqueWords);
}

我需要将节点存储并链接在一起,以允许我访问链接列表。

2 个答案:

答案 0 :(得分:1)

您编写的代码太复杂了。

#include <stdbool.h>
#include <assert.h>
#include <stddef.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>

#define STRING(x) #x
#define STRINGIFY(x) STRING(x)

#define BUFFER_SIZE 100

typedef struct node_tag {
    char *data;
    struct node_tag *next;
} node_t;

node_t* node_create(char const *word)
{
    node_t *new_node = calloc(1, sizeof *new_node);
    if (!new_node)
        return NULL;

    new_node->data = malloc(strlen(word) + 1);
    if (!new_node->data) {
        free(new_node);
        return NULL;
    }

    strcpy(new_node->data, word);
    return new_node;
}

void node_free(node_t *node)
{
    assert(node && node->data);

    free(node->data);
    free(node);
}

node_t* node_advance(node_t *node)
{
    assert(node);
    return node->next;
}

typedef struct list_tag {
    node_t *head;
    node_t *tail;
    size_t length;
} list_t;

list_t list_create(void)
{
    list_t list = { NULL, NULL, 0 };
    return list;
}

void list_free(list_t *list)
{
    assert(list);

    for (node_t *current_node = list->head; current_node;) {
        node_t *next_node = node_advance(current_node);
        node_free(current_node);
        current_node = next_node;       
    }
}

bool list_append(list_t *list, char const *word)
{
    assert(list && word);

    node_t *new_node = node_create(word);
    if (!new_node) {
        return false;
    }

    if (!list->tail) {
        list->head = list->tail = new_node;
    }
    else {
        list->tail->next = node_create(word);
        list->tail = list->tail->next;
    }

    ++(list->length);
    return true;
}

bool list_contains(list_t *list, char const *word)
{
    assert(list && word);

    for (node_t *current_node = list->head; current_node; current_node = node_advance(current_node)) {
        if (strcmp(current_node->data, word) == 0)
            return true;
    }

    return false;
}

void list_print(list_t *list)
{
    assert(list);

    for (node_t *current_node = list->head; current_node; current_node = node_advance(current_node)) {
        puts(current_node->data);
    }
}

int main(void)
{
    char const *filename = "test.txt";
    FILE *input = fopen(filename, "r");
    if (!input) {
        fprintf(stderr, "Couldn't open \"%s\" for reading :(\n\n", filename);
        return EXIT_FAILURE;
    }

    size_t unique_words = 0;
    list_t words_list = list_create();

    for (char buffer[BUFFER_SIZE + 1]; fscanf(input, "%" STRINGIFY(BUFFER_SIZE) "s", buffer) == 1;) {
        if (!list_contains(&words_list, buffer))
            ++unique_words;

        if (!list_append(&words_list, buffer)) {
            fclose(input);
            list_free(&words_list);
            fputs("Not enough memory :(\n\n", stderr);
            return EXIT_FAILURE;
        }       
    }

    puts("Words found:");
    list_print(&words_list);
    printf("\nNumber of unique words: %zu\n\n", unique_words);

    fclose(input);
    list_free(&words_list);
}

答案 1 :(得分:0)

这是代码中的一些问题:

  • 头文件丢失。您至少需要<stdio.h><stdlib.h><string.h>
  • }之前缺少fclose(inputFile);
  • 函数createWord应该分配一个单词的副本,否则所有节点都指向main()中的同一数组,其中fscanf()写入从文件中读取的最后一个单词。
  • li>
  • 您应通过告诉fscanf()要存储到目标数组的最大字符数来防止缓冲区溢出:fscanf(inputFile, "%99s", word)

这是createWord的修改版本:

static List *createWord(const char *word) {
    List *node = (List *)malloc(sizeof(List));
    if (node) {
        node->word = strdup(wordPtr);
        node->count = 1;
    }
    return node;
}