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

C++ FileIO功能实现异常求助:文件名无效及内容显示问题

C++文件IO功能修复:文件名无效与姓氏显示问题解决

问题概述

  • 控制台仅在初始时显示文本文件中的姓名字符串,后续输入新姓名后该内容实际未存入程序数据结构,导致无法被后续操作调用
  • 文件名输入功能无效,程序始终读取硬编码的File.txt文件

问题根源与修复方案

1. 文件名硬编码问题

原代码直接使用File.open("File.txt");,完全忽略用户输入的文件名变量line。修复时需替换为用户输入的文件名,并增加文件打开失败的判断逻辑。

2. 文件内容未存入程序数据结构

原代码仅将文件内容输出到控制台,未将这些姓名添加到names向量中,导致后续操作无法访问这些数据。需在读取每一行后,将姓名处理为程序所需格式(last, first)并加入向量。

3. 输入顺序导致的读取异常

原代码先调用Menu(),其中的cin.ignore()会清空输入缓冲区,导致后续的文件名输入被跳过。需调整顺序,先获取文件名,再进入菜单循环。

修复后的完整代码

#include <iostream>
#include <string>
#include <vector>
#include <sstream> 
#include <fstream>

using namespace std;

// function declarations 
int Menu();
void processName(string name, vector<string> &names, int &count);
void displayName(vector<string> &names, int count);
string getLastNames(vector<string> &names, int count);

int main()
{ 
    vector<string> names;
    int count = 0;
    ifstream File;
    string line;

    // 先获取文件名
    cout << "Enter file name: ";
    getline(cin, line);
    
    // 使用用户输入的文件名打开文件
    File.open(line);
    if (!File.is_open()) {
        cout << "Failed to open file: " << line << endl;
    } else {
        // 读取文件每一行并处理姓名
        while (getline(File, line)) { 
            processName(line, names, count);
            // 输出已处理的姓名
            cout << names.back() << endl;
        }
        File.close();
    }

    // 进入菜单循环
    int choice = Menu();
    while (choice != 0)
    {      
        switch (choice)
        {
            case 1: {
                string name;
                cout << "Enter name: ";
                getline(cin, name);
                processName(name, names, count);
            } break;
            
            case 2: { displayName(names, count); } break;
    
            case 3: { 
                cout << getLastNames(names, count) << endl; 
            } break;
            case 0: {
                return 0; 
            } break; 
        }
        choice = Menu(); 
    }
    return 0; 
}

// 提取姓名处理逻辑为独立函数,复用文件读取和手动输入的场景
void processName(string name, vector<string> &names, int &count)
{ 
    // 处理姓名格式为last, first
    int pos = name.find(' ');
    if(pos != string::npos) {
        string first = name.substr(0, pos);
        string last = name.substr(pos+1);
        name = last + "," + first;
    }
    names.push_back(name);
    count++; 
}

// 菜单函数
int Menu() {
    int choice;
    cout << "\n1. Add a name" << endl;
    cout << "2. Display names " << endl;
    cout << "3. Show all Last Names" << endl;
    cout << "0. Quit" << endl;
    cout << "Enter a option: ";
    cin >> choice;
    
    while (choice < 0 || choice > 3)
    { 
        cout << "Choice not on list: ";
        cin >> choice;
    }
    cin.ignore();
    return choice; 
}

// 生成姓氏字符串
string getLastNames(vector<string> &names, int count) {
    stringstream ss;
    for (int i = 0; i<count; i++)
    {
        int pos = names[i].find(',');
        if (pos != string::npos) {
            ss << "\"" << names[i].substr(0, pos) << "\", ";
        } else {
            ss << "\"" << names[i] << "\", ";
        }
    }
    string result = ss.str();
    // 移除最后多余的逗号和空格(可选优化)
    if (!result.empty()) {
        result.pop_back();
        result.pop_back();
    }
    return result;
}

// 显示所有姓名
void displayName(vector<string> &names, int count)
{ 
    if (count == 0)
    {
        cout << "No names to display" << endl;
        return; 
    }
    for (int i = 0; i<count; i++)
    { 
        cout << names[i] << endl;
    } 
}

修复说明

  • 新增processName函数,统一处理姓名格式转换逻辑,避免代码重复
  • 调整输入顺序,先获取文件名再显示菜单,解决输入缓冲区干扰问题
  • 替换硬编码文件名,使用用户输入的文件名打开文件,并增加打开失败提示
  • 文件读取的姓名会被存入names向量,后续操作(添加新姓名、显示姓名、生成姓氏列表)都能包含这些数据
  • 优化getLastNames函数,移除结果末尾多余的逗号和空格

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.11 02:15:36