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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.11 07:48:17