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

使用Ctrl-D终止C++日期预订程序时错误输出提示信息的原因及修复方案

问题原因分析

你遇到的问题核心在于循环时机判断和输入失败后的变量状态:

当按下Ctrl-D时,标准输入流cin会触发eofbit(文件结束标志)并进入失败状态,但你的main函数里while (cin)是在循环开始时检查流状态——如果上一次循环结束时流还是正常的,就会进入循环执行get(date)。此时get里的cin >> date.year会失败,但date变量的内容不会被清空,仍然保留着上一次输入的旧值。之后程序继续调用add函数,检查这个旧日期,发现它已经在预订列表里,就错误输出了“已被预订”的提示。

简单来说:输入结束后,程序误用上一次的旧日期执行了预订检查,导致了错误输出。

修复方案

这里有几种简单且有效的修复方式,按推荐程度排序:

方案1:让get函数返回输入是否成功

修改get函数,让它在每次输入操作后检查cin的状态,一旦失败就返回false,提前终止循环,避免执行后续的add操作:

#include <iostream>
#include <vector>
using namespace std;

struct Date_Type {
    int year;
    int month;
    int day;
};

// 修改get函数,返回bool表示输入是否成功
bool get(Date_Type& date) {
    cout << "Mata in datum: ";
    // 逐个检查输入操作是否成功
    if (!(cin >> date.year)) return false;
    cin.ignore(1); // 忽略分隔符'-'
    if (!(cin >> date.month)) return false;
    cin.ignore(1);
    if (!(cin >> date.day)) return false;
    return true;
}

void add(vector<Date_Type>& dates, Date_Type& date) {
    bool check_date = false;
    for (int i = 0; i < dates.size(); i++) {
        if (date.year == dates[i].year && date.month == dates[i].month && date.day == dates[i].day) {
            check_date = true;
            break; // 找到重复后直接跳出循环,优化性能
        }
    }
    if (!check_date) {
        dates.push_back(date);
        cout << "Bokning gjord!" << endl;
    } else {
        cout << "Kan ej göra bokning, detta datum är redan bokat!" << endl;
    }
}

int main() {
    Date_Type date{};
    vector<Date_Type> dates{};
    // 只有当get成功时,才执行add
    while (get(date)) {
        add(dates, date);
    }
    return 0;
}

这个方案逻辑清晰,把输入有效性检查封装在get函数里,主循环只处理有效的输入。另外我还在add函数里加了break,找到重复日期后就停止遍历,优化了一点性能。

方案2:在main里调用get后立即检查cin状态

如果你不想修改get函数的返回值,可以在main里调用get之后马上检查cin是否正常,失败就直接跳出循环:

int main() {
    Date_Type date{};
    vector<Date_Type> dates{};
    while (cin) {
        get(date);
        // 检查输入是否失败,失败则终止循环
        if (!cin) break;
        add(dates, date);
    }
    return 0;
}

这个方案改动最小,适合快速修复,但相比方案1,输入有效性的检查没有和输入逻辑封装在一起,代码稍显零散。

额外优化:处理输入分隔符的鲁棒性

你的cin.ignore(1)假设用户输入的分隔符是单个字符(比如'-'),但如果用户输入了多个分隔符(比如2021--04-15)或者其他字符,可能会导致后续输入错误。可以改成忽略所有非数字字符,直到遇到下一个数字或者流结束:

cin.ignore(numeric_limits<streamsize>::max(), '-');

不过这个需要包含<limits>头文件,属于额外的鲁棒性优化,不是解决当前问题必须的,但能让程序更健壮。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.28 08:37:45