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

程序可写入文本文件但读取时触发访问违例错误,求助排查

解决fscanf_s读取文件时的访问违例(Access Violation)问题

嘿,我看你遇到了fscanf_s读取文件时的访问违例问题——写入正常但读取直接崩了,错误指向stdio.h的第1092行,这个问题大概率和参数传递、内存初始化或者格式匹配有关,咱们一步步来捋清楚:

可能的问题根源

  • fscanf_s参数不完整:fscanf_s是微软的安全版本scanf,对于%s格式符,必须额外传入缓冲区的大小作为参数。你代码里写的MAX_STRING_LEN - ...看起来没写完,如果这里参数缺失或者数值错误,fscanf_s会不知道缓冲区的边界,直接越界写入内存,触发访问违例。
  • Product结构体的name成员未正确初始化:如果你的Product结构体里name是char*类型(而非固定大小的char数组),那局部变量temp的name会是一个野指针,直接用%s写入会导致非法内存访问。
  • 读写格式不匹配:如果写入文件时的格式和读取时的fscanf_s格式字符串不对应(比如顺序错了、空格处理不对),会导致解析过程中错误地写入内存区域,引发崩溃。

具体解决方案

  1. 补全fscanf_s的参数
    对于%s,必须传入缓冲区的大小,正确的写法应该是这样的:

    // 如果temp.name是固定数组,用_countof获取大小更安全
    int moreData = fscanf_s(stream, "%s", temp.name, (unsigned)_countof(temp.name));
    // 或者用你定义的MAX_STRING_LEN(确保数组大小和这个宏一致)
    int moreData = fscanf_s(stream, "%s", temp.name, (unsigned)MAX_STRING_LEN);
    

    注意这里的大小参数要传无符号整数,别漏了。

  2. 确认Product结构体的定义
    确保name是固定大小的char数组,比如:

    #define MAX_STRING_LEN 256
    typedef struct {
        char name[MAX_STRING_LEN]; // 这里是数组,不是指针!
        char type;
        double price;
        int qty;
    } Product;
    

    如果非要用char*,那读取前必须先给temp.name分配足够的内存(比如temp.name = malloc(MAX_STRING_LEN);),用完记得释放。

  3. 严格匹配读写的格式字符串
    比如写入时你用的是:

    fprintf(stream, "%s %c %.2lf %d\n", prod.name, prod.type, prod.price, prod.qty);
    

    那读取时的fscanf_s必须对应相同的格式,还要注意%c的空白问题——前面的%s会跳过空白,但%c会读取任何字符(包括空格、换行),所以最好在%c前加个空格跳过空白:

    int moreData = fscanf_s(stream, "%s %c %lf %d", 
                          temp.name, (unsigned)_countof(temp.name), 
                          &temp.type, 
                          &temp.price, 
                          &temp.qty);
    

    另外,要检查返回值moreData,如果不等于你要读取的参数个数(这里是4),说明格式不匹配或者文件读取到末尾了。

  4. 检查文件流的状态
    写完文件后一定要fclose,然后再重新打开读取;如果是同一个流读写,记得用fseek(stream, 0, SEEK_SET)把文件指针移回开头,不然会从文件末尾开始读,导致错误。

完整示例代码

这里给你一个能正常读写的小例子,参考一下:

#include <stdio.h>
#include <stdlib.h>
#define MAX_STRING_LEN 256

typedef struct {
    char name[MAX_STRING_LEN];
    char type;
    double price;
    int qty;
} Product;

// 写入产品到文件
void writeProduct(FILE* stream) {
    Product sample = {"Orange", 'F', 2.49, 80};
    fprintf(stream, "%s %c %.2lf %d\n", sample.name, sample.type, sample.price, sample.qty);
}

// 从文件读取产品
int readProduct(FILE* stream) {
    Product temp;
    int readCount = fscanf_s(stream, "%s %c %lf %d",
                            temp.name, (unsigned)_countof(temp.name),
                            &temp.type,
                            &temp.price,
                            &temp.qty);
    
    if (readCount == 4) {
        printf("读取成功:%s | %c | %.2lf | %d\n", temp.name, temp.type, temp.price, temp.qty);
        return 1;
    } else if (readCount != EOF) {
        printf("格式不匹配或部分读取\n");
        return 0;
    }
    return 0;
}

int main() {
    FILE* fp;

    // 写入文件
    if (fopen_s(&fp, "products.txt", "w") != 0) {
        printf("打开文件写入失败\n");
        return 1;
    }
    writeProduct(fp);
    fclose(fp);

    // 读取文件
    if (fopen_s(&fp, "products.txt", "r") != 0) {
        printf("打开文件读取失败\n");
        return 1;
    }
    while (readProduct(fp));
    fclose(fp);

    return 0;
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.22 09:33:20