使用C语言sscanf解析文件出现段错误,求基于sscanf的修复方案
问题分析与解决方案
段错误的核心原因
- 未限制
sscanf读取长度:直接用%s会无限制读取非空白字符,一旦输入长度超过你分配的缓冲区大小(lhsdata5字节、rhsdata15字节),就会触发缓冲区溢出,破坏堆内存结构导致段错误。 - 非法内存访问:
rhsdata[strlen(rhsdata)-1] = '\0';在rhsdata未被正确初始化时(比如行格式不符合预期),strlen(rhsdata)会返回随机值,减1后可能为负数,导致访问非法内存地址。 - 格式串冗余:
sscanf的%s会自动跳过空白字符(包括换行),格式串末尾的\n完全多余。 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
相关产品推荐
相关产品推荐

