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

C语言程序无法读取txt坐标数据:输出全0且读取循环不终止

问题分析与解决方案

核心问题汇总

  • feof循环判断错误:while(!feof(fp))是典型的错误用法,读取失败后仍会继续执行循环,导致出现无效值且无法终止。
  • 三角函数参数错误:cos和sin要求传入弧度值,但代码里把弧度转成了度数fi计算,直接导致坐标转换结果完全错误。
  • 文件编码不兼容:Unicode格式(如UTF-16)包含BOM头,会干扰fscanf的数值解析,引发读取失败。
  • 结构体类型引用错误:calloc中使用sizeof(exp_point),C语言中结构体类型需加struct前缀,否则会编译报错。
  • 旋转矩阵公式错误:原代码的y分量旋转计算符号有误,导致旋转结果不符合预期。

具体修复步骤

  1. 替换循环判断逻辑:用fscanf的返回值判断是否成功读取两个数值,确保只有读取到有效坐标对时才进入循环:
    while(fscanf(fp, "%lf %lf", &x, &y) == 2)
    
  2. 修正三角函数参数:直接使用原始弧度值FI计算,删除多余的度数转换:
    // 删除错误的度数转换行:double fi=FI*180/PI;//fi in degress
    x1=(x-X0)*cos(FI)+(y-Y0)*sin(FI);
    y1=(y-Y0)*cos(FI)-(x-X0)*sin(FI); // 修正旋转矩阵的y分量符号
    
  3. 调整文件格式:将txt文件保存为UTF-8无BOM或ANSI格式,用空格/制表符分隔坐标对即可(fscanf会自动跳过任意空白字符)。
  4. 修正calloc的类型参数:
    lim=(struct exp_point *)calloc(i,sizeof(struct exp_point));
    arr=(struct exp_point *)calloc(j,sizeof(struct exp_point));
    
  5. 初始化变量:给x、y等变量初始赋值,避免读取失败时出现垃圾值:
    double d,x=0.0,y=0.0,x1=0.0,y1=0.0;
    

修正后的完整代码

#include <stdio.h>
#include <math.h>
#include <stdlib.h>
#include <time.h>
#define N 10
#define PI 3.14159265359

int i,j;

double const X0=5,Y0=5,FI=0.7854;//FI in rads

struct exp_point{
    double x,y;
    double x1,y1;
    int line;
};


int main(){
    double d,x=0.0,y=0.0,x1=0.0,y1=0.0;
    i=0,j=0;
    FILE *fp;
    
    if ((fp=fopen("points2D_uni.txt","r"))==NULL) {
        printf("error reading file....\n");
        exit(1);
    } else {
        // 用fscanf返回值判断是否成功读取两个数
        while(fscanf(fp, "%lf %lf", &x, &y) == 2) {
            printf("x=%lf   y=%lf\n",x,y);
            // 使用弧度FI计算旋转,修正旋转矩阵的y分量符号
            x1=(x-X0)*cos(FI)+(y-Y0)*sin(FI);
            y1=(y-Y0)*cos(FI)-(x-X0)*sin(FI);
            d=sqrt(pow(x1-X0,2)+pow(y1-Y0,2)); // 用sqrt代替pow(...,0.5)更高效
            if(d>10.0)
                i++;
            else j++;
        }
        fclose(fp);
        printf("i=%d   j=%d\n",i,j);
        
        struct exp_point *lim;
        struct exp_point *arr;
        
        // 修正sizeof的结构体类型引用
        lim=(struct exp_point *)calloc(i,sizeof(struct exp_point));
        arr=(struct exp_point *)calloc(j,sizeof(struct exp_point));
        printf("total points: %d\n",i+j);
        
        // 释放内存避免泄漏
        free(lim);
        free(arr);
    }
    
    return 0;   
}

额外注意事项

  • 编译时需要链接math库,比如GCC编译命令:gcc your_code.c -o output -lm
  • 如果文件中存在空行或非数值内容,fscanf会读取失败并退出循环,可根据需求添加错误处理逻辑。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.23 11:47:28