C语言如何使用scanf为struct位段、结构体、枚举变量赋值
问题核心原因
C语言标准明确规定,位段成员不具备独立的内存地址,无法通过&取地址运算符获取其指针,而scanf的所有格式化输入占位符都要求传入对应类型的指针参数,因此直接给位段成员传参调用scanf必然失败。
不同类型变量的输入实现方案
1. 结构体位段成员输入
统一通过临时变量中转实现:
- 先定义和位段基础类型一致的临时变量
- 用
scanf读取输入到临时变量 - 再将临时变量赋值给位段成员
修正后的代码示例:
#include <stdio.h> typedef struct{ unsigned int _1_:7; unsigned int _2_:7; unsigned int _3_:7; unsigned int _4_:7; unsigned int _5_:7; } grades; grades student; int main(){ unsigned int tmp; // 临时中转变量 scanf("%u", &tmp); // 可自行加边界校验,7位无符号数最大值为127,避免溢出 if(tmp <= 127) { student._1_ = tmp; } return 0; }
注:位段赋值时要注意输入值不能超过位段的最大可表示范围,否则会发生截断,导致结果不符合预期。
2. 普通结构体成员输入
非位段的普通结构体成员,只要是完整的可寻址类型,直接对成员取地址传入scanf即可,示例:
#include <stdio.h> typedef struct { int id; char name[20]; float score; } Student; int main() { Student s; scanf("%d", &s.id); // 基础类型成员直接取地址 scanf("%s", s.name); // 数组成员本身就是首地址,不需要加& scanf("%f", &s.score); return 0; }
3. 枚举类型变量输入
枚举类型底层实现为整数类型,但scanf没有直接对应枚举的占位符,同样通过临时整数中转:
#include <stdio.h> typedef enum { FRESHMAN, SOPHOMORE, JUNIOR, SENIOR } Grade; int main() { Grade g; int tmp; scanf("%d", &tmp); // 可自行校验枚举取值范围,避免非法值 if(tmp >= FRESHMAN && tmp <= SENIOR) { g = tmp; } return 0; }
如果需要接收枚举字面量字符串(比如输入SENIOR完成赋值),需要自行实现字符串到枚举值的映射逻辑,scanf本身不支持直接识别枚举常量名。
内容的提问来源于stack exchange,提问作者XxCharbonChainsxX
相关产品推荐
相关产品推荐

