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

写入二进制文件时遇'Stack around the variable 's' was corrupted'错误求助

解决“Stack around the variable 's' was corrupted.”错误的方案

错误根源分析

你的代码触发栈损坏错误的核心原因是类型不匹配导致的内存越界写入,同时还有几处逻辑问题需要修正:

  • 结构体中多个char类型字段(如an、tip、data.zi等)被用scanf("%d")读取整数,%d会向目标地址写入4字节(int类型大小),而char仅占1字节,直接覆盖栈上相邻内存,破坏栈的完整性。
  • feof的使用逻辑错误,会导致最后一次无效读取仍进入循环。
  • 未显式将文件指针定位到末尾,可能导致写入位置不符合预期。

修复步骤及完整代码

  1. 对char类型字段,改用%hhd格式符读取(适配char类型的整数输入);对于单个字符tip,改用%c并处理输入缓冲区的换行符。
  2. 修正feof的使用逻辑,通过fread的返回值判断是否读取成功。
  3. 写入前显式调用fseek将指针移到文件末尾。
  4. 处理fgets读取姓名时可能残留的换行符问题。

修复后的代码:

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

typedef struct {
    int nrmat;
    char nume[30];
    char an;
    int grp;
    char tip;
    struct {
        char zi;
        char luna;
        int an;
    } data;
    struct {
        char oraint;
        char minutint;
    } intrare;
    struct {
        char oraies;
        char minuties;
    } iesire;
} STUDENT;

void sosire(const char* nume) {
    FILE* f = fopen(nume, "r+b");
    if (!f) {
        printf("\nFisierul nu a putut fi deschis.");
        return;
    }

    STUDENT s;
    // 用fread返回值判断读取是否成功,替代feof逻辑
    while (fread(&s, sizeof(STUDENT), 1, f) == 1);

    printf("\nSosire student:\n");
    printf("Nr. matricol: ");
    scanf("%d", &s.nrmat);

    // 清空输入缓冲区换行符,避免fgets读取空行
    while (getchar() != '\n');
    printf("Nume student: ");
    fgets(s.nume, sizeof(s.nume), stdin);
    // 去掉fgets读取的末尾换行符
    s.nume[strcspn(s.nume, "\n")] = '\0';

    printf("An: ");
    scanf("%hhd", &s.an);
    printf("Grupa: ");
    scanf("%d", &s.grp);

    // 读取单个字符前清空缓冲区残留换行
    while (getchar() != '\n');
    printf("Tip (Biblioteca <'B'> sau Laboratoare <'L'>: ");
    scanf("%c", &s.tip);

    printf("Data\nZi: ");
    scanf("%hhd", &s.data.zi);
    printf("Luna: ");
    scanf("%hhd", &s.data.luna);
    printf("An: ");
    scanf("%d", &s.data.an);

    printf("Ora sosire\nOra: ");
    scanf("%hhd", &s.intrare.oraint);
    printf("Minute: ");
    scanf("%hhd", &s.intrare.minutint);

    // 显式将文件指针移到末尾
    fseek(f, 0, SEEK_END);
    fwrite(&s, sizeof(STUDENT), 1, f);

    fclose(f);
}

int main() {
    sosire("SecvStud.dat");
    return 0;
}

关键修改说明

  • %hhd格式符:专门用于读取char类型的整数,避免写入超出字段大小的内存。
  • 输入缓冲区处理:用while(getchar() != '\n')清空缓冲区的换行符,防止fgets或%c读取到残留的换行。
  • fread循环逻辑:直接判断fread的返回值(成功读取的元素数),比feof更可靠。
  • 显式文件定位:fseek(f, 0, SEEK_END)确保写入操作在文件末尾执行。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.26 00:53:19