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

scanf返回值忽略错误排查:结构体实现员工年龄统计代码问题

解决C++员工信息管理代码的scanf返回值警告及逻辑问题

问题描述

编写了一段通过结构体实现员工信息管理并筛选最年轻、最年长员工的C++代码,编译器触发**Return value ignored: 'scanf'**警告,且无法正确筛选目标员工。原代码如下:

#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
#include <stdio.h>
#include <string>
using namespace std;

int main()
{
    setlocale(LC_ALL, "Russian");
    struct worker
    {
        char surname[22], posada[15], osvita[25];
        int birthday, salary;
    };
    int kol; cout << "Введите кол-во робітників: "; cin >> kol;
    cout << "Введите поочередно строки с ведомостью:\nПрiзвище   Посада    Освіта    Рік народження   Зарплатня" << endl;

    worker* z = new worker[kol];
    for (int i = 0; i < kol; i++) {
        scanf("%s %s %s %i %i", z[i].surname, z[i].posada, z[i].osvita, &z[i].birthday, &z[i].salary);
    }
    setlocale(LC_ALL, "Russian");
    cout << "Прiзвище   Посада    Освіта    Рік народження   Зарплатня" << endl;

    for (int i = 0; i < kol; i++) {
        cout << z[i].surname << "\t" << z[i].posada << "\t" << z[i].osvita << "\t" << z[i].birthday << "\t" << z[i].salary << endl;
    }
    cout << "Найстарший і наймолодний робітники:\nПрiзвище   Посада    Освіта    Рік народження   Зарплатня" << endl;

    int min, max;
    int max_index = 0, min_index = 0;
    min = z[0].birthday;
    max = z[0].birthday;
    for (int i = 0; i < kol; i++) {
        if (max < z[i].birthday) {max_index = i;}
        if (min > z[i].birthday) {min_index = i;}
        printf("% s % s % s % i % i\n", z[i].surname, z[i].posada, z[i].osvita, z[i].birthday, z[i].salary);
    }
    setlocale(LC_ALL, "Russian");
    cout << "Наймолодний робітник: " << z[min_index].surname<< endl;
    cout << "Найстарший робітник: " << z[max_index].surname << endl;
    setlocale(LC_ALL, ".OCP");
    delete[]z;
    return 0;
}

问题根源

  1. scanf返回值未处理:scanf返回成功读取的参数数量,代码未检查该返回值,编译器会抛出警告,且无法发现输入失败的情况。
  2. 筛选逻辑错误:寻找最大/最小出生年份时,仅更新索引但未同步更新max和min变量,导致后续判断失效,无法正确定位目标员工,且输出时的索引对应关系也存在错误。
  3. 格式符错误:printf中的格式符与空格之间多了空格(如% s),会导致输出格式混乱。
  4. 冗余本地化设置:多次重复调用setlocale,属于无效冗余操作。

修正后的代码

#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
#include <stdio.h>
#include <string>
using namespace std;

int main()
{
    setlocale(LC_ALL, "Russian"); // 仅需初始化一次本地化设置
    struct worker
    {
        char surname[22], posada[15], osvita[25];
        int birthday, salary;
    };

    int kol; 
    cout << "Введите кол-во робітників: "; 
    cin >> kol;
    cout << "Введите поочередно строки с ведомостью:\nПрiзвище   Посада    Освіта    Рік народження   Зарплатня" << endl;

    worker* z = new worker[kol];
    for (int i = 0; i < kol; i++) {
        // 处理scanf返回值,检查输入是否成功
        if (scanf("%s %s %s %i %i", z[i].surname, z[i].posada, z[i].osvita, &z[i].birthday, &z[i].salary) != 5) {
            cerr << "Ошибка ввода данных для работника #" << i+1 << endl;
            delete[] z;
            return 1;
        }
    }

    cout << "Прiзвище   Посада    Освіта    Рік народження   Зарплатня" << endl;
    for (int i = 0; i < kol; i++) {
        cout << z[i].surname << "\t" << z[i].posada << "\t" << z[i].osvita << "\t" << z[i].birthday << "\t" << z[i].salary << endl;
    }

    cout << "Найстарший і наймолодний робітники:\nПрiзвище   Посада    Освіта    Рік народження   Зарплатня" << endl;

    int min_birth = z[0].birthday, max_birth = z[0].birthday;
    int max_index = 0, min_index = 0;
    for (int i = 0; i < kol; i++) {
        // 更新最大出生年份(对应最年轻员工)
        if (max_birth < z[i].birthday) {
            max_birth = z[i].birthday;
            max_index = i;
        }
        // 更新最小出生年份(对应最年长员工)
        if (min_birth > z[i].birthday) {
            min_birth = z[i].birthday;
            min_index = i;
        }
        // 修正printf格式符,去掉多余空格
        printf("%s %s %s %i %i\n", z[i].surname, z[i].posada, z[i].osvita, z[i].birthday, z[i].salary);
    }

    cout << "Наймолодний робітник: " << z[max_index].surname << endl;
    cout << "Найстарший робітник: " << z[min_index].surname << endl;

    delete[] z;
    return 0;
}

核心修改说明

  • 处理scanf返回值:添加判断,确保每次输入都成功读取5个参数,若失败则提示错误并释放内存后退出。
  • 修复筛选逻辑:更新索引的同时同步更新min_birth和max_birth的值,保证后续判断的准确性,同时修正了输出时的索引对应关系。
  • 修正格式符:移除printf格式符中的多余空格,保证输出格式正确。
  • 清理冗余代码:移除重复的setlocale调用,仅保留初始化时的一次设置。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.08 20:10:48