跳过文件头后读取数据触发段错误(Status_access_violation)求排查
问题分析与解决
问题描述
尝试从固定格式的文件中读取数字,需先跳过文件头。目前跳过文件头的函数运行正常,但后续读取文件内容时触发段错误,错误码为Status_access_violation。文件格式示例:
P5;256 789;125;125 236 789...(大量数字)
问题代码
#include <ctype.h> #include <stdbool.h> #include <stdio.h> #include <stdlib.h> #include <string.h> FILE *salt_header(FILE *poza){ char gunoi1[2]; fscanf(poza, "%s", gunoi1); printf("%s\n", gunoi1); int gunoi2; fscanf(poza, "%d ", &gunoi2); printf("%d ", gunoi2); fscanf(poza, "%d", &gunoi2); printf("%d\n", gunoi2); fscanf(poza, "%d", &gunoi2); printf("%d\n", gunoi2); return poza; } int main() { FILE *poza; char gunoi1[2], *nume; nume = malloc(256 * sizeof(char *)); if(nume == NULL) exit(-11); scanf("%s", nume); poza = fopen(nume, "r"); if(poza == NULL){ printf("Failed to open file\n"); exit(-1); } poza = salt_header(poza); int numar; for(int i = 0; i < 3; i++){ fscanf(poza, "%d", &numar); printf("%d ", numar); } fclose(poza); free(nume); return 0; }
错误原因及修复方案
1. 缓冲区溢出触发段错误
salt_header函数中,char gunoi1[2];用来读取文件头的P5,但fscanf("%s", gunoi1)会读取整个字符串并自动添加终止符\0。P5加上终止符需要3个字节空间,而gunoi1仅2字节,直接导致缓冲区溢出,破坏栈上的文件指针等关键数据,后续操作文件时触发段错误。
修复:将gunoi1长度调整为至少3字节,比如char gunoi1[10];,同时用%2s限制读取长度避免溢出:
char gunoi1[10]; fscanf(poza, "%2s", gunoi1);
2. malloc内存分配错误
main函数中nume = malloc(256 * sizeof(char *));错误使用sizeof(char *),应该用sizeof(char)。虽然多数系统中char*为4/8字节,分配空间足够,但属于不规范写法,可能在特殊环境出问题。
修复:改为nume = malloc(256 * sizeof(char));,或简化为nume = malloc(256);(sizeof(char)固定为1)。
3. 文件头读取逻辑适配问题
文件中的分隔符是中文分号;,但fscanf默认仅跳过空白字符,若文件中用中文分号分隔字段,当前逻辑会读取错误内容(比如把P5;256当成一个字符串),导致后续读取位置偏移错误。
修复:读取字段后手动跳过中文分号及空白字符:
// 跳过中文分号及空白 int c; while ((c = fgetc(poza)) != EOF && c != ';');
修复后的示例代码
#include <ctype.h> #include <stdbool.h> #include <stdio.h> #include <stdlib.h> #include <string.h> FILE *salt_header(FILE *poza){ char gunoi1[10]; fscanf(poza, "%2s", gunoi1); printf("%s\n", gunoi1); // 跳过中文分号及空白 int c; while ((c = fgetc(poza)) != EOF && c != ';'); int gunoi2; fscanf(poza, "%d", &gunoi2); printf("%d ", gunoi2); while ((c = fgetc(poza)) != EOF && c != ';'); fscanf(poza, "%d", &gunoi2); printf("%d\n", gunoi2); while ((c = fgetc(poza)) != EOF && c != ';'); fscanf(poza, "%d", &gunoi2); printf("%d\n", gunoi2); return poza; } int main() { FILE *poza; char *nume; nume = malloc(256 * sizeof(char)); if(nume == NULL) exit(-11); scanf("%s", nume); poza = fopen(nume, "r"); if(poza == NULL){ printf("Failed to open file\n"); exit(-1); } poza = salt_header(poza); int numar; for(int i = 0; i < 3; i++){ if(fscanf(poza, "%d", &numar) != 1){ printf("\n读取数字失败"); break; } printf("%d ", numar); } fclose(poza); free(nume); return 0; }
内容的提问来源于stack exchange,提问作者macaidk
相关产品推荐
相关产品推荐

