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

跳过文件头后读取数据触发段错误(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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.06 22:20:27