You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何将Linked List保存到文件?链表写入文件无限循环致文件过大

链表保存到文件时无限写入的问题修复

问题描述

无法将链表(liste chainée)保存到文件中,程序会持续写入直到文件大小达到1.4GB。确认问题出在保存函数,因为链表填充过程正常。

原程序代码

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
/***valeur d'un capteur d'humidite***/
typedef struct
{
    int heure;
    int minute;
}Date;
typedef struct//valeur d'une cellule/noeud
{
    char id[10];
    char id_capt[10];
    Date date_hr;
    int val_hum;//float ou int
}valeurs_hum;

typedef struct//liste chainee
{
    valeurs_hum capt;
    struct Element* suivant;
}Element;

typedef struct Liste Liste;
struct Liste
{
    Element *premier;
};
/************************************************/
Liste *initialisation()
{
    Liste *liste = malloc(sizeof(*liste));
    Element *nouveau = malloc(sizeof(*nouveau));//element->nouveau

    if (liste == NULL || nouveau == NULL)
    {
        exit(EXIT_FAILURE);
    }

    printf("Donner id = ");
    fflush(stdin);
    scanf("%s",nouveau->capt.id);
    if( strlen(nouveau->capt.id)==0)//peut etre ajouter au premier
    nouveau=NULL;
    else
    {
    printf("Donner id du capteur = ");
    fflush(stdin);
    scanf("%s",nouveau->capt.id_capt);
    printf("Donner date de prendre valeur d'humidite\n");
    printf("heure = ");
    scanf("%d",&nouveau->capt.date_hr.heure);
    printf("minite = ");
    scanf("%d",&nouveau->capt.date_hr.minute);
    //valeur du capteur aleatoire
    nouveau->capt.val_hum = rand() % 100 + 1;

    nouveau->suivant = NULL;
    liste->premier = nouveau;

    return liste;
    }
}
/********************************************/
void insertion(Liste *liste)
{
    /* Création du nouvel élément */
    Element *nouveau = malloc(sizeof(*nouveau));
    if (liste == NULL || nouveau == NULL)
    {
        exit(EXIT_FAILURE);
    }

    printf("Donner id = ");
    fflush(stdin);
    scanf("%s",nouveau->capt.id);
    if( strlen(nouveau->capt.id)==0)
    nouveau=NULL;
    else
    {
    printf("Donner id du capteur = ");
    fflush(stdin);
    scanf("%s",nouveau->capt.id_capt);
    printf("Donner date de prendre valeur d'humidite\n");
    printf("heure = ");
    scanf("%d",&nouveau->capt.date_hr.heure);
    printf("minite = ");
    scanf("%d",&nouveau->capt.date_hr.minute);
    //valeur du capteur aleatoire
    nouveau->capt.val_hum = rand() % 100 + 1;
        /* Insertion de l'élément au début de la liste */
        nouveau->suivant = liste->premier;
        liste->premier = nouveau;
        }
}
/*******************************************/
void afficherListe(Liste *liste)
{
    if (liste == NULL)
    {
        exit(EXIT_FAILURE);
    }

    Element *nouveau = liste->premier;//nouveau->courant

    while (nouveau != NULL)
    {
printf("\n id : %s", nouveau->capt.id);
printf("\n id du capteur : %s", nouveau->capt.id_capt);
printf("\n date de prendre valeur d'humidite = %d:%d",nouveau->capt.date_hr.heure,nouveau->capt.date_hr.minute);
printf("\n valeur du capteur :%d", nouveau->capt.val_hum);

nouveau = nouveau->suivant;
    }
    printf("\n");
}
/*************************************************/
void Sauvegarder(Liste *liste, FILE* pf)
{
int i;
Element *courant = liste->premier;

while(courant!=NULL)
fprintf(pf,"\n%s : %s : %d:%d : %d \n", courant->capt.id, courant->capt.id_capt, courant->capt.date_hr.heure,courant->capt.date_hr.minute,courant->capt.val_hum);
courant=courant->suivant;
}
/************************************************/
int main(void)
{
char* nomfich;
FILE * pf;
    int i,nbr_capt;
    Liste *l;
    Liste *l1;

nomfich=(char*)malloc(sizeof(char));
printf("\n Donnez le nom du fichier à créer :");
gets(nomfich);
/*--------------------------------------------*/
/*------------------Ecriture dans le fichier----------------*/
pf = fopen(nomfich, "a+");
//do{
    l=initialisation();

    printf("donner nbre capt = ");
    scanf("%d",&nbr_capt);
    for(i=0;i<nbr_capt;i++)
        insertion(l);
/*if( l==NULL)
break;
else*/
Sauvegarder(l, pf);
//}while(1);
fclose(pf);

return 0;
}

核心错误分析

你锁定的Sauvegarder函数确实是问题根源:

while(courant!=NULL)
fprintf(pf,"\n%s : %s : %d:%d : %d \n", courant->capt.id, courant->capt.id_capt, courant->capt.date_hr.heure,courant->capt.date_hr.minute,courant->capt.val_hum);
courant=courant->suivant;

C语言中,while循环若未用大括号{}包裹,只会执行紧跟其后的第一行代码。这里fprintf被反复执行,但courant=courant->suivant;不在循环体内,导致courant指针永远指向链表首节点,形成死循环,持续向文件写入相同内容,直到文件体积异常庞大。

修复方案

给while循环添加大括号,让指针移动语句进入循环体:

void Sauvegarder(Liste *liste, FILE* pf)
{
    Element *courant = liste->premier;

    while(courant!=NULL) {
        fprintf(pf,"\n%s : %s : %d:%d : %d \n", courant->capt.id, courant->capt.id_capt, courant->capt.date_hr.heure,courant->capt.date_hr.minute,courant->capt.val_hum);
        courant=courant->suivant;
    }
}

其他潜在问题修复

程序还有几个可能引发崩溃或异常的问题,建议一并修复:

  • 文件名内存分配不足:nomfich=(char*)malloc(sizeof(char));仅分配1字节,完全无法存储文件名,会导致内存越界。改为分配足够空间:
    char* nomfich = malloc(256 * sizeof(char)); // 分配256字节存储文件名
    
  • gets函数不安全:gets会引发缓冲区溢出,改用fgets并处理换行符:
    fgets(nomfich, 256, stdin);
    nomfich[strcspn(nomfich, "\n")] = '\0'; // 去除fgets读取的换行符
    
  • initialisation函数返回漏洞:输入空id时,未释放已分配内存且无返回值,会导致未定义行为:
    Liste *initialisation()
    {
        Liste *liste = malloc(sizeof(*liste));
        Element *nouveau = malloc(sizeof(*nouveau));
    
        if (liste == NULL || nouveau == NULL)
        {
            exit(EXIT_FAILURE);
        }
    
        printf("Donner id = ");
        fflush(stdin);
        scanf("%s",nouveau->capt.id);
        if( strlen(nouveau->capt.id)==0) {
            free(nouveau); // 释放已分配内存
            free(liste);
            return NULL;
        }
        else
        {
            // 原有初始化逻辑...
            return liste;
        }
    }
    
  • insertion函数内存泄漏:输入空id时,未释放已分配的nouveau内存:
    void insertion(Liste *liste)
    {
        Element *nouveau = malloc(sizeof(*nouveau));
        if (liste == NULL || nouveau == NULL)
        {
            exit(EXIT_FAILURE);
        }
    
        printf("Donner id = ");
        fflush(stdin);
        scanf("%s",nouveau->capt.id);
        if( strlen(nouveau->capt.id)==0) {
            free(nouveau); // 释放内存
            return;
        }
        else
        {
            // 原有插入逻辑...
        }
    }
    

内容的提问来源于stack exchange,提问作者skander

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.06 19:25:14