C语言打开txt并将字符串输入到链表中

把txt中的名字(一行一个)依次输入链表中,以便后续的插入删除输出等操作

运行结果:

img

代码:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
//每个名字的最大长度
#define MAXLEN 30

typedef struct _sta
{
    char* str;
}Sta;

typedef struct _stnode 
{
    Sta data;
    struct _stnode* next;
}LNode,*LinkList;


//初始化链表
void InitList(LinkList* head)
{
    (*head) = (LinkList)malloc(sizeof(LNode));
    (*head)->next = 0;
}

//读文件并采用尾插法插入链表
void CreateList(LinkList head,const char* filename)
{
    FILE* fp = 0;
    LinkList p,t;
    fp = fopen(filename,"r");
    if(fp == 0)
    {
        printf("文件读取错误!\n");
        return ;
    }

    //移动到链表末尾
    p = head;
    while(p->next)
        p = p->next;

    //读取文件
    while(!feof(fp))
    {
        t = (LinkList)malloc(sizeof(LNode));
        t->data.str = (char*)malloc(MAXLEN);
        t->data.str[0] = 0; //初始化
        t->next = NULL;
        fscanf_s(fp,"%s",t->data.str,MAXLEN);
        //将节点插入链表
        if(strlen(t->data.str)>0)//判断是否读取到数据
        {
            p->next = t;
            p = t;
        }else
        {
            free(t->data.str);
            free(t);
        }
        
    }
    //关闭
    fclose(fp);
}

//显示链表
void PrintList(LinkList head)
{
    LinkList p = head->next;
    while(p)
    {
        printf("%s ",p->data.str);
        p = p->next;
    }
    printf("\n");
}



int main()
{
    LinkList head = 0;
    const char* filename = "a.txt";
    InitList(&head);
    CreateList(head,filename);
    PrintList(head);

    return 0;

}


从文件里逐行读取名字,写入链表就行了吗?要不要有固定的头节点呢?

#include <stdio.h>
#include <math.h>


typedef struct _Node
{
    char name[20];
    struct _Node *next;
}Node;

void insertNode(Node *head,char name[])
{
    Node *p = head;
    while(p->next != NULL)
        p = p->next;
    Node *q = (Node*)malloc(sizeof(Node));
    strcpy(q->name,name);
    q->next = NULL;
    p->next = q;
}

int main()
{
    Node *head = (Node*)malloc(sizeof(Node));
    head->next= NULL;
    //
    FILE *fp = fopen("D:\\test.txt","r");
    char buf[100] = {0};
    if(fp == NULL)
        return 0;
    while(fgets(buf,100,fp) != NULL)
        insertNode(head,buf);
    fclose(fp);
    
    return 0;
}

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define MAX_SIZE 50

typedef struct _Node
{
    char name[MAX_SIZE];
    struct _Node *next;
} Node;

typedef struct _List
{
    Node *head;
    Node *tail;
} List;

List *create_list()
{
    List *list = (List *)malloc(sizeof(List));
    list->head = NULL;
    list->tail = NULL;
    return list;
}

void destroy_list(List *list)
{
    Node *p = list->head;
    while (p)
    {
        Node *q = p;
        p = p->next;
        free(q);
    }
    free(list);
}

void append_list(List *list, const char *name)
{
    Node *p = (Node *)malloc(sizeof(Node));
    strcpy(p->name, name);
    p->next = NULL;
    if (list->tail)
    {
        list->tail->next = p;
        list->tail = p;
    }
    else
    {
        list->head = p;
        list->tail = p;
    }
}

void print_list(const List *list)
{
    Node *p = list->head;
    while (p)
    {
        printf("%s\n", p->name);
        p = p->next;
    }
}

int main()
{
    char name[MAX_SIZE];
    List *list = create_list();
    FILE *file = fopen("input.txt", "r");
    if (!file)
    {
        perror("failed to open input.txt");
        return 1;
    }
    while (fgets(name, MAX_SIZE, file)) {
        name[strlen(name) - 1] = '\0'; // remove \n
        append_list(list, name);
    }
    fclose(file);
    print_list(list);
    destroy_list(list);
    return 0;
}

#include <stdio.h>
#include <stdlib.h>
#include <memory>

#define NAME_MAX_LENGTH   256   //名字的长度

typedef struct Link 
{
    char  name[NAME_MAX_LENGTH];
    struct Link* next;
}link;

/*  初始化链表
*/
link* initLink();

/*  链表插入函数
    p:链表
    name:插入的结点的数据域
    add:插入的位置
*/
link* insertElem(link* p, char* name, int add);

/*  删除结点函数
    p:代表操作链表
    add:代表删除节点的位置
*/
link* delElem(link* p, int add);

/*  查找结点的函数
    p:代表操作链表
    name:为目标结点的数据域的值
*/
int selectElem(link* p, char* name);

/*  更新结点的函数
    p:代表操作链表
    add:代表删除节点的位置
    newElem为新的数据域的值
*/
link* updateElem(link* p, int add, char* name);

/*  打印链表元素值
*/
void display(link* p);

int main() 
{
    link* p = initLink();

    FILE* fp = fopen("example.txt", "r");
    if (NULL == fp)
    {
        printf("fopen file failed. \n");
        return -1;
    }
    char name[NAME_MAX_LENGTH];
    memset(name, '\0', NAME_MAX_LENGTH);
    int addIndex = 1;
    while (NULL != fgets(name, NAME_MAX_LENGTH, fp))
    {
        p = insertElem(p, name, addIndex++);
        memset(name, '\0', NAME_MAX_LENGTH);
    }
    printf("读完文件后,链表元素为:\n");
    display(p);

    //TODO:对链表的后续操作:插入、删除、输出等操作,调用相应接口函数即可

    fclose(fp);
    return 0;
}
link* initLink() 
{
    //创建一个头结点
    link* p = (link*)malloc(sizeof(link));
    memset(p->name, '\0', sizeof(p->name));
    p->next = NULL;
    return p;
}
link* insertElem(link* p, char* name, int add)
{
    //创建临时结点temp
    link* temp = p;
    //首先找到要插入位置的上一个结点
    for (int i = 1; i < add; i++) 
    {
        temp = temp->next;
        if (temp == NULL)
        {
            printf("插入位置无效\n");
            return p;
        }
    }
    //创建插入结点c
    link* c = (link*)malloc(sizeof(link));
    strncpy(c->name, name, strlen(name));
    //向链表中插入结点
    c->next = temp->next;
    temp->next = c;
    return  p;
}
link* delElem(link* p, int add) 
{
    link* temp = p;
    //遍历到被删除结点的上一个结点
    for (int i = 1; i < add; i++) 
    {
        temp = temp->next;
        if (temp->next == NULL) 
        {
            printf("没有该结点\n");
            return p;
        }
    }
    //单独设置一个指针指向被删除结点,以防丢失
    link* del = temp->next;
    //删除某个结点的方法就是更改前一个结点的指针域
    temp->next = temp->next->next;
    //手动释放该结点,防止内存泄漏
    free(del);
    return p;
}
int selectElem(link* p, char* name)
{
    link* t = p;
    int i = 1;
    while (t->next) 
    {
        t = t->next;
        if (0 == strcmp(t->name, name)) 
        {
            return i;
        }
        i++;
    }
    return -1;
}
link* updateElem(link* p, int add, char* newName)
{
    link* temp = p;
    //temp指向首元结点
    temp = temp->next;
    //temp指向被删除结点
    for (int i = 1; i < add; i++)
    {
        temp = temp->next;
    }
    strncpy(temp->name, newName, strlen(newName));
    return p;
}

void display(link* p) 
{
    //将temp指针重新指向头结点
    link* temp = p;

    //只要temp指针指向的结点的next不是Null,就执行输出语句。
    while (temp->next) 
    {
        temp = temp->next;
        printf("%s \n", temp->name);
    }
    printf("\n");
}
不知道你这个问题是否已经解决, 如果还没有解决的话:

如果你已经解决了该问题, 非常希望你能够分享一下解决方案, 写成博客, 将相关链接放在评论区, 以帮助更多的人 ^-^