首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >C语言中基于数组的链表,问题是读取所有数据

C语言中基于数组的链表,问题是读取所有数据
EN

Stack Overflow用户
提问于 2020-12-08 07:36:47
回答 1查看 42关注 0票数 0

我尝试使用基于数组的链表从data.txt读入值,然后显示这些项。不需要对列表进行排序。目前,它只打印列表中的最后一项。我不确定我是在读整个列表,还是只读了最后一个单词。如果有任何建议,我将不胜感激。从前面开始,我做了一些修改。它编译了,但我得到了一个段错误,其中valgrind状态为“无效写入或大小为1”。

main.c

#包含

代码语言:javascript
复制
#include <stdlib.h>
#include <string.h>

#define WORD_SIZE 25
#define MAX_NODES 100
#define FILENAME "data.txt"

char buffer[WORD_SIZE];
int count = 0, i = 0;

typedef struct WORDNODE {
    char word[WORD_SIZE];
    struct WORDNODE *next;
} t_word_node;

t_word_node node_array[MAX_NODES];
t_word_node *free_list = NULL;
t_word_node *tail = NULL;

t_word_node *create_node(void);
void add_word(char *buffer, t_word_node **);

void node_init() {
    for(int count = 0; count < MAX_NODES-2; count++) {
        node_array[count].next = &node_array[count+1];
    }
    node_array[MAX_NODES - 1].next = NULL;
    free_list = &node_array[0];
}

void add_word(char *buffer, t_word_node **list) {
    t_word_node *temp = NULL;
        t_word_node *last = NULL;
        t_word_node *this = *list;

    temp = create_node();
    strcpy(temp->word, buffer);
    while(this && strcmp(buffer, this->word) > 0) {
        last = this;
        this = this->next;
    }
    if(last == NULL) {
            temp->next = this;
                *list = temp;
        } else {
            last->next = temp;
        temp->next = this;
    }
}


t_word_node *create_node() {
    t_word_node *new = NULL;

    if(free_list != NULL)
    {
        new = free_list;
        free_list = free_list->next;
    }
    return new;
}

void print_nodes(t_word_node *this) {
        if(this == NULL) {
                return;
        }
        while(this != NULL) {
                printf("%s\n", this->word);
                this = this->next;
                }
}

int main() {
    count = 0;
    FILE *infile;
    t_word_node *new_list = NULL;
    node_init();
    if((infile = fopen(FILENAME, "r")) != NULL) {
        while (fscanf(infile, "%s", buffer) != EOF) {
                    add_word(buffer, &new_list);
                }
            fclose(infile);
        }
    print_nodes(new_list);
        return 0;
}

data.txt

代码语言:javascript
复制
Kaleidoscope
Rainbow
Navy
Highway
Printer
Junk
Milk
Spectrum
Grapes
Earth
Horse
Sunglasses
Coffee-shop
Ice
Spice
Tennis racquet
Drill
Electricity
Fan
Meat
Clown
Weapon
Drink
Record
Spiral
Air
Data Base
Cycle
Snail
Child
Eraser
Meteor
Woman
Necklace
Festival
Eyes
Foot
Diamond
Chocolates
Explosive
Web
Rifle
Leather jacket
Aeroplane
Chisel
Hose
Flower
Space Shuttle
Radar
Hieroglyph
Ice-cream
Insect
Feather
Ears
Square
Software
Cup
Comet
Church
PaintBrush
Slave
Elephant
Sphere
Aircraft Carrier
Fork
Needle
Prison
Solid
Window
Dress
Knife
Spot Light
Onion
Horoscope
Chief
Crystal
Coffee
Microscope
Freeway
Fruit
Kitchen
Desk
Spoon
Pyramid
Restaurant
Adult
Potato
Egg
Telescope
Family
Sports-car
Television
Jet fighter
Thermometer
Wheelchair
X-ray
Sun
Worm
Church
EN

回答 1

Stack Overflow用户

发布于 2020-12-08 07:54:06

问题是你误用了你的tail指针作为temp指针。使用temp作为临时指针。接下来,验证读取的每个字是否适合WORD_SIZE数组,并验证每个分配。

代码语言:javascript
复制
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define WORD_SIZE 25
#define FILENAME "data.txt"

typedef struct WORDNODE {
    char word[WORD_SIZE];
    struct WORDNODE *next;
} t_word_node;

t_word_node *head, *tail, *temp;

t_word_node *create_node()
{
    return(t_word_node *)malloc(sizeof(t_word_node));
}

int main (int argc, char **argv) {
    
    char buffer[WORD_SIZE];
    FILE *infile;

    infile = fopen(argc > 1 ? argv[1] : FILENAME, "r");

    while (fgets (buffer, sizeof(buffer), infile) != NULL) {
        size_t len;
        buffer[(len = strcspn (buffer, "\n"))] = 0;
        if (len >= WORD_SIZE) {
            fputs ("error: word exceeds WORD_SIZE\n", stderr);
            continue;
        }
        if (!(temp = create_node())) {
            perror ("malloc-create_node()");
            return 1;
        }
        strcpy(temp->word, buffer);
        temp->next = NULL;
        if (head == NULL)
            head = tail = temp;
        else {
            tail->next = temp;
            tail = temp;
        }
    }
    temp = head;
    while (temp != NULL) {
        puts (temp->word);
        temp = temp->next;
    }
    return 0;
}

您有了一个插入指针--永远不需要遍历列表以在末尾插入(这就是tail指针的用途)。请注意,当第一个节点添加到列表中时,tail是如何初始化的。

示例使用/输出

不要硬编码文件名。这就是argcargvint main (int argc, char **argv)中的作用,将要读取的文件名作为第一个参数传递给您的程序,如果没有提供任何参数,则默认从FILENAME读取:

代码语言:javascript
复制
$ ./bin/llarraywords dat/datallwords.txt
Kaleidoscope
Rainbow
Navy
Highway
Printer
Junk
Milk
Spectrum
Grapes
Earth
Horse
Sunglasses
...
<snip>
...
Egg
Telescope
Family
Sports-car
Television
Jet fighter
Thermometer
Wheelchair
X-ray
Sun
Worm
Church

仔细检查一下,如果你还有其他问题,请告诉我。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/65191002

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档