C语言结构体录入int/float数据时SIGSEGV错误及编译警告求助
我来帮你拆解并解决这个问题——你遇到的SIGSEGV段错误和编译警告,本质都是scanf的使用错误导致的,咱们一步步修复:
1. 核心问题:scanf格式符与类型不匹配+未传指针
这是触发段错误和警告的直接原因:
height(int类型):你用了字符串格式符%3s,而且直接传了subj->height(int值)。scanf需要变量的地址来修改值,直接传int会被当成非法指针,访问无效内存引发SIGSEGV。修正为用%d格式符+传递地址:scanf("%d", &subj->height);weight(float类型):同理,用了错误的%6s格式符,且未传地址。修正为用%f格式符+传递地址:scanf("%f", &subj->weight);name/surname的格式符冗余:%64[^\n]s里的s是多余的——%[^\n]本身就是完整的格式说明符(读取所有非换行符的字符),加s会导致scanf尝试匹配一个s字符,引发输入失败。另外如果DIM=64,要给字符串终止符\0留1字节,所以限制最多读63个字符:scanf("%63[^\n]", subj->name); // 数组名本身就是指针,无需加&
2. 修复cleanBuffer的死循环隐患
原函数在输入流遇到EOF(比如用户按Ctrl+D)时,getchar()会返回EOF,而循环只判断c != '\n',会陷入死循环。同时要把char c改成int c——因为getchar()返回的是int类型(包含ASCII值和EOF),用char存储会截断EOF,导致无法正确判断:
int cleanBuffer(){ int cont= 0; int c; do{ cont++; c = getchar(); }while(c != '\n' && c != EOF); // 加上EOF判断 return cont; }
3. 完整修正后的代码
struct.h
#define DIM 64 typedef struct{ char name[DIM]; char surname[DIM]; int height; float weight; }Record; void insRecord(Record *subj); int cleanBuffer();
struct.c
#include "struct.h" #include <stdio.h> int cleanBuffer(){ int cont= 0; int c; do{ cont++; c = getchar(); }while(c != '\n' && c != EOF); return cont; }
main.c
#include "struct.h" #include <stdio.h> void insRecord(Record *subj){ printf("Name: "); scanf("%63[^\n]", subj->name); cleanBuffer(); printf("Surname: "); scanf("%63[^\n]", subj->surname); cleanBuffer(); printf("Height (cm): "); scanf("%d", &subj->height); cleanBuffer(); printf("Weight (kg): "); scanf("%f", &subj->weight); cleanBuffer(); } int main() { Record subj; insRecord(&subj); // 可选:打印录入结果验证 printf("\nYou entered:\nName: %s\nSurname: %s\nHeight: %dcm\nWeight: %.2fkg\n", subj.name, subj.surname, subj.height, subj.weight); return 0; }
补充说明
%[^\n]是scanf专门用来匹配字符集合的格式符,%[^\n]表示读取所有非换行符的字符,后面不能加s,否则会被当成需要匹配的普通字符,导致输入逻辑混乱。- 限制读取字符数(比如
%63[^\n])是为了避免缓冲区溢出,保证字符串末尾能正常添加终止符\0。
内容的提问来源于stack exchange,提问作者Momoa
相关产品推荐
相关产品推荐

