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

使用C语言sscanf解析文件出现段错误,求基于sscanf的修复方案

问题分析与解决方案

段错误的核心原因

  1. 未限制sscanf读取长度:直接用%s会无限制读取非空白字符,一旦输入长度超过你分配的缓冲区大小(lhsdata5字节、rhsdata15字节),就会触发缓冲区溢出,破坏堆内存结构导致段错误。
  2. 非法内存访问:rhsdata[strlen(rhsdata)-1] = '\0';在rhsdata未被正确初始化时(比如行格式不符合预期),strlen(rhsdata)会返回随机值,减1后可能为负数,导致访问非法内存地址。
  3. 格式串冗余:sscanf的%s会自动跳过空白字符(包括换行),格式串末尾的\n完全多余。
  4. line变量可能未正确定义:如果line是指针而非固定大小的数组,sizeof line会返回指针长度(通常8字节),fgets读取内容时会缓冲区溢出,破坏内存。

仅用sscanf的修正代码

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

int main() {
    FILE *filePtr = fopen("your_file.txt", "r");
    if (!filePtr) {
        perror("Failed to open file");
        return 1;
    }

    // 确保line是足够大的数组,避免fgets缓冲区溢出
    char line[100];
    // 分配内存时留足终止符空间,后续用格式串限制读取长度
    char* lhsdata = malloc(5 * sizeof(char));
    char* rhsdata = malloc(15 * sizeof(char));
    if (!lhsdata || !rhsdata) {
        perror("Failed to allocate memory");
        fclose(filePtr);
        return 1;
    }

    while (fgets(line, sizeof(line), filePtr)) {
        // 跳过空行(包括仅含换行的行)
        if (line[0] == '\n') break;

        // 用%4s限制lhsdata最多读4个字符(留1位给终止符),%14s限制rhsdata
        // 检查sscanf返回值,确保成功读取2个字段
        if (sscanf(line, "%4s %14s", lhsdata, rhsdata) == 2) {
            printf("%s %s\n", lhsdata, rhsdata);
        }
        // 可添加else处理格式错误的行
    }

    // 释放内存
    free(lhsdata);
    free(rhsdata);
    fclose(filePtr);
    return 0;
}

关键修正点说明

  • 限制读取长度:%4s对应lhsdata的5字节大小(4个有效字符+1个终止符),%14s对应rhsdata的15字节大小,彻底避免缓冲区溢出。
  • 检查sscanf返回值:确保只有成功读取两个字段时才执行后续操作,避免处理未初始化的缓冲区。
  • 移除非法内存操作:删除rhsdata[strlen(rhsdata)-1] = '\0';,因为sscanf的%s会自动为读取的字符串添加终止符,且换行符会被%s自动忽略。
  • 正确定义line数组:使用固定大小的字符数组,保证sizeof line返回缓冲区实际长度,避免fgets读取溢出。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.11 15:45:41