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

结构体指针成员赋值问题:从文本文件读取数据失败

搞懂结构体指针与fscanf的正确用法

我来帮你理清这里的问题,核心就是搞懂指针、取地址符和结构体成员访问符的用法~

首先先拆解你的两个尝试:

尝试1的情况

你的第一个写法:

void foo(A *a){ fscanf(fp,"%d",&(*a).x); }

其实这个写法是完全正确的,不会有编译错误或运行问题(前提是fp已经正确打开)。这里的(*a).x是先对指针a解引用(*a拿到结构体实例),再访问成员x;&是取这个成员的地址,而fscanf刚好需要传入变量的地址来写入数据,所以逻辑没问题,只是写法有点冗余。

尝试2的问题

第二个写法:

void foo(A *a){ fscanf(fp,"%d",a->x); }

这里直接触发段错误的原因很明确:a->x是结构体成员的值(int类型),但fscanf的第二个参数要求传入int*(也就是int变量的地址)。你把一个int值当成内存地址传进去,程序会尝试往这个非法地址写数据,自然会触发段错误,编译器如果开了高警告级别(比如-Wall)也会提示类型不匹配。

关键符号的清晰解释

你困惑的*、&、->,其实可以这样理解:

  • *(解引用):当放在指针变量前,用来获取指针指向的实际数据。比如*a就是指针a指向的A结构体实例。
  • &(取地址):用来获取变量的内存地址,返回对应类型的指针。比如&a->x就是拿到成员x的地址,类型是int*。
  • ->(结构体指针成员访问):这是C语言提供的语法糖,完全等价于(*指针).成员。比如a->x和(*a).x是一模一样的效果,只是写起来更简洁。

推荐的正确写法

基于上面的解释,最简洁清晰的写法是:

void foo(A *a){
    // 确保fp已经正确打开(比如fopen返回的不是NULL)
    fscanf(fp, "%d", &a->x);
}

如果你想更直观,也可以拆成两步:

void foo(A *a){
    int *x_ptr = &a->x; // 先拿到x的地址
    fscanf(fp, "%d", x_ptr);
}

最后别忘了一个前提:使用fscanf前一定要确认文件指针fp是有效的(比如调用fopen后检查返回值不为NULL),否则不管怎么写都会出问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.27 08:53:11