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

结构体中指针使用问题:多组输入后输出均为最后一组值

问题分析:结构体指针存储输入后全部显示最后一组数据的原因

嘿,我来帮你拆解这个问题——你说三次输入不同的ID和密码,结果所有输出都是最后一组的5和6,而且要求结构体内部必须用指针对吧?咱们先从代码里的问题说起:

1. sizeof在函数参数里的误用(小问题但影响输入)

你在game函数里用了sizeof id和sizeof password,但这里的id和password是指针参数,不是数组。在C里,数组作为函数参数传递时会退化成指针,所以sizeof id拿到的是指针的大小(比如64位系统是8字节),根本不是你想要的输入缓冲区大小。这会导致fgets只能读几个字符,不过这还不是让所有输出都一样的核心原因。

2. 所有结构体元素都指向同一块内存(核心问题!)

这才是导致所有输出都是最后一组数据的关键:

  • 你在main里应该是重复用了同一个id和password缓冲区(不管是全局的还是main里的局部数组)。
  • 每次调用game时,你把login->dts和login->password直接指向这个缓冲区的地址。
  • 当你输入新的一组数据时,会直接覆盖这个缓冲区里的旧内容——而所有结构体的指针都盯着这块内存,最后自然全显示最后一次输入的内容。

打个比方:你有三个便签,每个都写着“看桌上的纸条”,然后你每次把桌上的纸条换成新内容,最后三个便签指向的都是同一张纸条,当然显示的都是最后换的内容啦。

3. 代码里还有几个明显的语法bug

  • main里调用的gameInfo应该是game函数吧?笔误了~
  • main里的printf语句括号不匹配,格式字符串也没写全,编译肯定过不了。
  • printGame的循环逻辑有问题:for (int i = 1; i < 4; i++)同时又做login++,这会导致循环提前结束或者访问超出结构体数组的范围。

解决方案(保持结构体用指针的要求)

要解决这个问题,咱们得给每个结构体的dts和password分配独立的内存空间,不让它们都挤在同一个缓冲区里。下面是修改后的完整示例代码:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

// 先补全结构体定义(你之前没贴,假设是这样)
typedef struct gameInfo {
    char *dts;
    char *password;
} gameInfo;

// 假设你的cl函数是用来去掉fgets读入的换行符
void cl(char *str) {
    str[strcspn(str, "\n")] = '\0';
}

void game(struct gameInfo *login, const char *id, const char *password) {
    // 为dts分配足够的内存(+1是给字符串结束符'\0'留位置)
    login->dts = malloc(strlen(id) + 1);
    if (login->dts != NULL) {
        strcpy(login->dts, id);
    }
    // 同样为password分配独立内存
    login->password = malloc(strlen(password) + 1);
    if (login->password != NULL) {
        strcpy(login->password, password);
    }
}

void printGame(struct gameInfo *login, int count) {
    for (int i = 0; i < count; i++) {
        printf("%d %35s %35s\n", i+1, login[i].dts, login[i].password);
    }
}

int main(void) {
    gameInfo login[3]; // 定义3个结构体元素,存三组数据
    char id_buf[100];  // 临时缓冲区,每次输入先存在这儿
    char pwd_buf[100];

    for (int i = 0; i < 3; i++) {
        printf("game dts:   ");
        fgets(id_buf, sizeof(id_buf), stdin);
        cl(id_buf); // 去掉换行符

        printf("game password:   ");
        fgets(pwd_buf, sizeof(pwd_buf), stdin);
        cl(pwd_buf);

        // 把临时缓冲区的内容复制到结构体的独立内存里
        game(&login[i], id_buf, pwd_buf);

        // 临时验证下当前输入是否正确存储
        printf("当前输入已保存:%s %s\n", login[i].dts, login[i].password);
    }

    // 打印所有存储的条目
    printf("\n所有输入内容:\n");
    printGame(login, 3);

    // 别忘了释放动态分配的内存,避免内存泄漏
    for (int i = 0; i < 3; i++) {
        free(login[i].dts);
        free(login[i].password);
    }

    return 0;
}

关键修改说明

  • 用id_buf和pwd_buf作为临时输入缓冲区,每次输入先存在这儿。
  • 在game函数里用malloc为每个结构体的dts和password分配独立内存,再把临时缓冲区的内容复制过去——这样每个结构体的指针都指向自己的专属内存块,不会被后续输入覆盖。
  • 修复了printGame的循环逻辑,避免指针越界。
  • 添加了内存释放的代码,养成良好习惯,防止内存泄漏。

总结

说白了就是所有结构体指针都指向了同一块内存,新输入把旧内容覆盖了。只要给每个结构体成员分配独立的动态内存,就能让每组数据都安安稳稳待在自己的地盘里,不会互相干扰啦~

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.04 16:45:29