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

如何动态分配结构体内存并存储不同类型数据?解决输入异常问题

问题分析与解决方案

核心问题

  • 内存分配不足:原代码里malloc(sizeof(details))只给单个结构体分配了内存,当输入的n大于1时,会出现越界访问,直接导致程序异常。
  • 无法读取带空格的姓名:scanf("%s")碰到空格、换行就会停止读取,根本没法获取带空格的姓名,而且用%*c清缓冲区的方式不靠谱,容易残留垃圾数据干扰后续输入。
  • 用gets处理整数输入行不通:gets是读取整行字符串的函数,要是输入前缓冲区里剩了换行符,它会直接读个空行,转成int自然就失败了。

修正后的代码

#include <stdio.h>
#include <stdlib.h>
#include <string.h> // 新增strchr函数需要的头文件

typedef struct node{
    char name[15];
    int age;
} details;

void entry(details*, int);

int main()
{
    int n, i;
    printf("Enter number of details\n");
    // 读取数量后彻底清空缓冲区
    scanf("%d", &n);
    while (getchar() != '\n');

    // 分配n个结构体的内存,同时检查分配是否成功
    details* ptr = malloc(n * sizeof(details));
    if (!ptr) {
        puts("Memory allocation failed");
        return 1;
    }

    entry(ptr, n);

    // 输出结果
    for(i = 0; i < n; i++)
        printf("\n%s\n%d\n\n", (ptr+i)->name, (ptr+i)->age);

    free(ptr); // 释放内存,避免泄漏
    return 0;
}

void entry(details *det, int n)
{
    int i;
    for(i = 0; i < n; i++){
        printf("Enter name:");
        // 用fgets读取带空格的姓名
        fgets((det+i)->name, sizeof((det+i)->name), stdin);
        // 去掉fgets读进来的换行符
        char *nl = strchr((det+i)->name, '\n');
        if (nl) *nl = '\0';

        printf("Enter Age:");
        scanf("%d", &(det+i)->age);
        // 读完年龄后清空缓冲区,避免影响下一次姓名输入
        while (getchar() != '\n');
    }
}

关键修改说明

  • 内存分配修正:改成malloc(n * sizeof(details)),确保能装下n条数据,同时加了分配失败的判断,防止空指针出问题。
  • 姓名读取替换:用fgets代替scanf("%s"),它能读取整行内容,包括空格,之后用strchr找到换行符并替换成字符串结束符,避免姓名末尾带换行。
  • 缓冲区处理升级:用while(getchar() != '\n')彻底清空缓冲区,比%*c靠谱多了,不管缓冲区剩多少字符都能清干净。
  • 添加内存释放:用完动态内存后必须free,不然会造成内存泄漏。

注意点

  • 结构体里name数组长度是15,fgets最多读14个有效字符,输入姓名别太长,不然会被截断。
  • 要是输入的姓名刚好占满14个字符,fgets不会读取换行符,这时候后面的缓冲区清理逻辑也不会出错,因为scanf读整数时会自动跳过前面的空白字符。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.12 01:37:44