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

从标准输入将字符串存入结构体字段时遇循环赋值问题

问题分析与解决方案

我来帮你搞定这个问题!你现在遇到的麻烦主要来自两个核心点:

  • gets()函数早就被C标准废弃了,它完全不做缓冲区边界检查,不仅容易导致程序崩溃,还存在严重的安全漏洞,这也是你输入失败的潜在原因之一;
  • 你定义的是7个独立的结构体变量(a1到a7),普通循环没办法自动依次访问这些变量——循环里没法凭空从a1切换到a2再到a3,这才是你没法批量赋值的关键。

正确的实现思路

1. 改用结构体数组

把单独的a1-a7改成结构体数组,这样就能通过索引遍历每个结构体,这是循环处理多个同类型变量的标准操作。

2. 使用安全的输入函数

用fgets()替代gets(),fgets()可以指定读取的最大字符数,彻底避免缓冲区溢出,同时我们需要手动处理掉输入末尾的换行符(因为fgets()会把换行符也读入缓冲区)。

完整示例代码

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

struct automobile {
    char marca[15];
    char modello[20];
    char targa[7];
    unsigned cilindrata;
};

int main() {
    // 定义结构体数组,包含7个元素,替代原来的a1-a7
    struct automobile autos[7];
    int i;

    for (i = 0; i < 7; i++) {
        printf("请输入第%d辆车的marca:", i+1);
        // 使用fgets读取,最多读取14个字符(留一个位置给字符串结束符'\0')
        fgets(autos[i].marca, sizeof(autos[i].marca), stdin);
        
        // 去掉fgets读取到的换行符,避免后续输出出现多余空行
        autos[i].marca[strcspn(autos[i].marca, "\n")] = '\0';

        // 可以继续添加其他字段的输入逻辑,比如modello、targa等
        printf("请输入第%d辆车的modello:", i+1);
        fgets(autos[i].modello, sizeof(autos[i].modello), stdin);
        autos[i].modello[strcspn(autos[i].modello, "\n")] = '\0';
    }

    // 测试输出,验证输入是否成功
    for (i = 0; i < 7; i++) {
        printf("第%d辆车:marca=%s, modello=%s\n", i+1, autos[i].marca, autos[i].modello);
    }

    return 0;
}

关键细节解释

  • 结构体数组:struct automobile autos[7] 创建了7个连续的结构体实例,通过autos[0]到autos[6]就能依次访问,完美适配循环逻辑;
  • fgets的安全用法:fgets(buffer, size, stdin) 中第二个参数用sizeof(autos[i].marca)可以自动获取数组长度,避免硬编码数字导致的错误;
  • 换行符处理:strcspn()函数会返回第一个匹配换行符的位置,把这个位置设为'\0',就能去掉输入末尾的换行符,保证字符串格式正常;
  • 为什么gets必须淘汰:gets()不会检查输入长度,如果用户输入的字符超过marca数组的容量,会直接溢出缓冲区,引发内存错误、程序崩溃甚至恶意代码注入风险,所以C11标准已经彻底移除了这个函数。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.20 10:33:58