C语言中向链表写入数据时出现错误求助
排查链表写入数据时的错误及修复方案
首先,我先梳理你代码里已经暴露的几个关键问题,再给你补充完整的链表写入逻辑:
1. 直接修改argv参数导致的未定义行为
你的代码里用了 namefile = strcat(argv[cont], ".txt");,但argv指向的字符串是只读内存,直接用strcat修改会触发未定义行为(比如程序崩溃)。正确的做法是先为文件名分配足够的内存:
// 计算需要的内存长度:原参数长度 + 4(".txt"的长度)+ 1(终止符) int name_len = strlen(argv[cont]) + 5; namefile = (char*)malloc(name_len); if (namefile == NULL) { perror("malloc failed"); exit(EXIT_FAILURE); } strcpy(namefile, argv[cont]); strcat(namefile, ".txt");
用完namefile后记得用free(namefile);释放内存。
2. 文件操作的不完整与资源泄漏
- 你的
fseek代码没写完,应该是fseek(arq, -1, SEEK_END);?但如果文件是空的,这个操作会失败,需要先判断文件大小。 - 打开文件后没有调用
fclose(arq);,会导致文件资源泄漏。 - 读取文件内容的逻辑缺失,你需要从文件中读取数据,然后创建链表节点插入链表。
3. 链表写入逻辑缺失
你定义了链表结构,但没有实现创建节点和插入链表的核心代码。这里给你补充一个示例,假设你要从文件中读取整数写入双向链表:
完整的链表节点创建与插入函数
// 创建一个新节点 Nbig* create_node(int num) { Nbig* node = (Nbig*)malloc(sizeof(Nbig)); if (node == NULL) { perror("malloc failed"); exit(EXIT_FAILURE); } node->number = num; node->nseg = NULL; node->nant = NULL; return node; } // 向双向链表尾部插入节点 void insert_tail(Nbig** head, Nbig* new_node) { if (*head == NULL) { *head = new_node; return; } Nbig* temp = *head; while (temp->nseg != NULL) { temp = temp->nseg; } temp->nseg = new_node; new_node->nant = temp; }
4. 完整的文件读取并写入链表的示例逻辑
把这些整合到你的main函数中,替换原来的文件操作部分:
// 假设文件中每行一个整数 int num; while (fscanf(arq, "%d", &num) != EOF) { Nbig* node = create_node(num); insert_tail(&list, node); } fclose(arq); // 记得关闭文件
5. 其他需要注意的细节
argc>3的判断可能不符合你的需求,如果你的程序是接收多个文件名参数,应该判断argc >= 2?或者明确你的参数规则,比如./program [option1] [option2] file1 file2...,这样cont应该从2或3开始,根据你的实际参数设计调整。- 所有动态分配的内存(节点、namefile)在程序结束前要记得释放,避免内存泄漏。可以写一个销毁链表的函数:
void destroy_list(Nbig** head) { Nbig* temp; while (*head != NULL) { temp = *head; *head = (*head)->nseg; free(temp); } } // 在main函数结束前调用 destroy_list(&list);
修复后的完整代码片段示例
#include <stdio.h> #include <stdlib.h> #include <string.h> typedef struct NBIG{ int number; struct NBIG *nseg; struct NBIG *nant; }Nbig; Nbig* create_node(int num) { Nbig* node = (Nbig*)malloc(sizeof(Nbig)); if (node == NULL) { perror("malloc failed"); exit(EXIT_FAILURE); } node->number = num; node->nseg = NULL; node->nant = NULL; return node; } void insert_tail(Nbig** head, Nbig* new_node) { if (*head == NULL) { *head = new_node; return; } Nbig* temp = *head; while (temp->nseg != NULL) { temp = temp->nseg; } temp->nseg = new_node; new_node->nant = temp; } void destroy_list(Nbig** head) { Nbig* temp; while (*head != NULL) { temp = *head; *head = (*head)->nseg; free(temp); } } int main(int argc,char *argv[]) { char *namefile; Nbig *list=NULL; int cont; FILE *arq; // 假设参数格式是:程序名 其他参数 文件名1 文件名2... if (argc < 3) { // 根据你的实际参数数量调整 printf("Usage: %s [options] file1 file2...\n", argv[0]); return EXIT_FAILURE; } for(cont=2; cont < argc; cont++){ // 假设从第2个参数开始是文件名 int name_len = strlen(argv[cont]) + 5; namefile = (char*)malloc(name_len); if (namefile == NULL) { perror("malloc failed"); destroy_list(&list); exit(EXIT_FAILURE); } strcpy(namefile, argv[cont]); strcat(namefile, ".txt"); printf("Processing file: %s\n", namefile); arq = fopen(namefile, "r"); if(arq == NULL) { perror("Failed to open file"); free(namefile); continue; } // 读取文件中的整数并写入链表 int num; while (fscanf(arq, "%d", &num) != EOF) { Nbig* node = create_node(num); insert_tail(&list, node); } fclose(arq); free(namefile); } // 可以在这里添加链表遍历打印的代码,验证写入是否成功 Nbig* temp = list; printf("Linked list content:\n"); while (temp != NULL) { printf("%d ", temp->number); temp = temp->nseg; } printf("\n"); destroy_list(&list); return EXIT_SUCCESS; }
你可以根据实际需求调整文件读取的格式(比如不是整数的话,修改fscanf或者用fgets读取字符串),但核心的问题和修复思路就是以上这些。
内容的提问来源于stack exchange,提问作者user48571
相关产品推荐
相关产品推荐

