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

如何不使用循环回到代码顶部?Flames程序goto输入异常问题

解决Flames程序中goto跳转后无法输入姓名的问题

我明白你遇到的困扰了——用goto实现重复输入功能后,第二次循环时用户没法正常输入姓名,直接被跳过了。这其实是输入缓冲区残留的换行符在捣乱,咱们一步步把问题解决掉:

问题根源

当你用cin>>t读取用户的Y/N选择时,用户输入完会按回车,这个回车对应的换行符\n会留在输入缓冲区里。下一次循环调用getline(cin, fname1)时,getline会把这个残留的换行符当作空行输入,直接跳过了用户的真实输入,看起来就像没法输入姓名了。

解决方案

在cin>>t之后,手动清理输入缓冲区里的残留字符,特别是那个换行符。可以用cin.ignore(numeric_limits<streamsize>::max(), '\n')来实现,它会把缓冲区里直到换行符的所有字符都清除干净。

另外,你的代码里还有几个小细节可以优化:

  1. 遍历字符串时,i<=fname1.length()会导致越界(字符串索引是从0到length()-1),应该改成i<fname1.length()
  2. "Aquaintance"拼写有误,正确拼写是"Acquaintance"
  3. 处理total为0或取模后为0的情况,避免输出错误结果

下面是修复后的完整代码:

#include <iostream>
#include <string>
#include <limits> // 需包含此头文件使用numeric_limits
using namespace std;

int main() {
start: 
    system("cls");
    char t;
    string fname1,fname2;
    int i,x,y,name1len=0,name2len=0,b,total,name1spc=0,name2spc=0;

    cout<<"Enter your full name: "; 
    getline(cin,fname1);
    cout<<"Enter partners name: "; 
    getline(cin,fname2);
    cout<<endl;

    // 转大写时修复越界问题
    for(i=0;i<fname1.length();i++ ) { 
        fname1[i]=toupper(fname1[i]); 
    }
    for(i=0;i<fname2.length();i++) { 
        fname2[i]=toupper(fname2[i]); 
    }

    x=fname1.length(); 
    y=fname2.length();

    // 统计空格
    for(i=0;i<x;i++) { 
        if(fname1[i]==' ') { 
            name1spc++; 
        } 
    }
    for(i=0;i<y;i++) { 
        if(fname2[i]==' ') { 
            name2spc++; 
        } 
    }

    // 计算共同字符(保留原有逻辑)
    for(i=0;i<fname1.length();i++) {
        for(b=0;b<fname2.length();b++) {
            if(fname1[i]==fname2[b]) { 
                name1len++; 
                break; 
            }
        }
    }
    for(i=0;i<fname2.length();i++) {
        for(b=0;b<fname1.length();b++) {
            if(fname2[i]==fname1[b]) { 
                name2len++; 
                break; 
            }
        }
    }

    name1len=name1len-name1spc;
    name2len=name2len-name2spc;
    total=name1len+name2len;

    // 处理特殊情况,避免错误输出
    if(total == 0) {
        cout<<"No valid characters entered"<<endl;
    } else {
        if(total>6) { 
            total=total%6; 
            // 取模后为0对应FLAMES的第6个结果(Sweethearts)
            if(total == 0) total =6;
        }
        switch(total) {
            case 1: cout<<fname1<<" and "<<fname2<<" are Friends"<<endl; break;
            case 2: cout<<fname1<<" and "<<fname2<<" are Lovers"<<endl; break;
            case 3: cout<<fname1<<" and "<<fname2<<" are Acquaintance"<<endl; break;
            case 4: cout<<fname1<<" and "<<fname2<<" are Married"<<endl; break;
            case 5: cout<<fname1<<" and "<<fname2<<" are Enemies"<<endl; break;
            case 6: cout<<fname1<<" and "<<fname2<<" are Sweethearts"<<endl; break;
        }
    }

    cout<<"Would you like to enter another name? Y/N?"; 
    cin>>t;
    // 清理输入缓冲区,清除残留的换行符
    cin.ignore(numeric_limits<streamsize>::max(), '\n');

    if(t=='Y' || t=='y') { 
        goto start; 
    } else if(t=='N' || t=='n') { 
        cout<<"THANKS"<<endl; 
        system("pause"); 
    } else{ 
        return 0; 
    }
}

关键修改点说明

  1. 添加<limits>头文件,用于调用numeric_limits实现缓冲区清理
  2. 在cin>>t之后添加cin.ignore(...),彻底清除输入缓冲区的残留内容
  3. 修复字符串遍历的越界问题(i<=改为i<)
  4. 修正"Acquaintance"的拼写错误
  5. 处理total为0或取模后为0的情况,避免错误输出

这样修改后,goto跳转后用户就能正常输入姓名了。虽然goto能满足你不能用循环的需求,后续如果想优化代码,也可以考虑用函数封装输入和计算逻辑,用递归代替goto(这个场景下递归不会有栈溢出问题),不过目前的方案完全符合你的需求。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.14 07:46:36