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

为何C程序循环次数≥2时无法读取板球运动员姓名输入?如何修复?

问题原因分析
  • 姓名读取格式串错误:原代码中scanf("%[^ ]s", &player[i].name);存在两处问题:一是%[^ ]已经表示读取所有字符直到换行符,后面额外的s属于冗余格式,会强制要求输入中包含s字符,否则scanf会失败;二是player[i].name是数组首地址,无需添加&符号。
  • 输入缓冲区残留换行符:使用%d读取整数后,用户输入的换行符会残留在输入缓冲区中。当循环进入下一次迭代时,scanf("%[^ ]")会直接读取到这个换行符,将其视为姓名的输入内容,导致跳过真实的姓名输入步骤。
  • 场均得分类型不匹配:场均得分run是float类型,但代码中用%d(整数格式)读取,会导致数据解析错误,破坏内存中的数据结构。
  • 最高得分逻辑反转:查找最高场均得分的循环中,错误地将high的值赋给player[i].run,而非将更高的player[i].run赋值给high,无法正确找到最大值。
修复方案及完整代码

针对上述问题,逐一修复后的代码如下:

//Write a C program to create a record containing the name of cricketer (char array), his age
//(integer), and number of test matches (integer) that he has played and the average runs
//(float) that he has scored in each test match. Create an array of structures to hold records
//of 20 such cricketers and then write a program to read these records and print it, also find
//the cricketer which has the highest average.
#include <stdio.h>
#include <string.h>

struct cricketer
{
    char name[40];
    int age;
    int match;
    float run;
};

int main()
{
    struct cricketer player[20];
    int recordCount = 3; // 测试用3条记录,可修改为20

    for(int i=0; i<recordCount; i++)
    {
        printf("Enter details for cricketer %d
", i+1);
        
        printf("Name: ");
        // 用空格跳过缓冲区残留的空白字符,%[^
]读取直到换行
        scanf(" %[^
]", player[i].name); 

        printf("Age: ");
        scanf("%d", &player[i].age);

        printf("Number of matches played: ");
        scanf("%d", &player[i].match);

        printf("Average runs: ");
        scanf("%f", &player[i].run); // 用%f匹配float类型
    }

    // 打印所有记录
    printf("

=== All Cricketer Records ===
");
    for(int i=0; i<recordCount; i++)
    {
        printf("

Cricketer #%d:
", i+1);
        printf("Name: %s
", player[i].name);
        printf("Age: %d
", player[i].age);
        printf("Matches played: %d
", player[i].match);
        printf("Average runs: %.2f
", player[i].run);
    }

    // 查找最高场均得分的运动员
    float highestAvg = player[0].run;
    int topPlayerIndex = 0;
    for(int i=1; i<recordCount; i++)
    {
        if(player[i].run > highestAvg)
        {
            highestAvg = player[i].run;
            topPlayerIndex = i;
        }
    }

    printf("

=== Top Performer ===
Highest average runs: %.2f
Player name: %s
", highestAvg, player[topPlayerIndex].name);

    return 0;
}

关键修复点说明

  1. 姓名读取修正:scanf(" %[^ ]", player[i].name);中的前置空格会自动跳过输入缓冲区中的所有空白字符(包括残留的换行符),确保读取到真实的姓名输入;同时去掉了冗余的s格式符。
  2. 场均得分格式修正:改用%f格式符读取float类型的场均得分,避免类型不匹配问题。
  3. 最高得分逻辑修正:当发现更高的场均得分时,更新highestAvg的值并记录对应的运动员索引,最终可以输出对应的运动员姓名,增强实用性。
  4. 可选优化:如果姓名中包含空格,原%[^ ]仍然可以正常读取;若想进一步避免缓冲区问题,也可以使用fgets读取姓名后去除换行符:
    fgets(player[i].name, sizeof(player[i].name), stdin);
    player[i].name[strcspn(player[i].name, "
    

")] = '';

内容的提问来源于stack exchange,提问作者chintamani chaudhari
相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.21 02:23:14