繁体   English   中英

当仅在一行上提示输入一次时,如何确保用户输入名字和姓氏?

[英]How to ensure user inputs a first and last name when only prompting for input once on one line?

C++ 初学者在这里。 我将 playerData 的结构存储在一个向量中(称为播放器库)。 该结构的一个成员是玩家的名字(在结构中存储为 1 个字符串,如“Julio Jones”)。 在使用我的应用程序时,如果用户输入的名称不在我程序的预制播放器库中,系统会提示用户将新名称添加到播放器库以供将来使用。 名称输入代码为:

std::string input{};
std::cout << "Enter the player " << m_name << " traded: ";
std::getline(std::cin, input);

在使用程序结束时,用户可以保存他们对播放器库所做的任何更改以备将来使用。 我通过将矢量写入 txt 文件来做到这一点

if (startAnswer == "exit")
{
    std::cout << "Exiting Trade Analzyer...\n";
    std::ofstream myfile;
    myfile.open("playerbank.txt");
    for (int k = 0; k < allPlayers.size(); ++k)
    {
        myfile << allPlayers[k].playerName << ' ' << allPlayers[k].playerPosition << ' ' << allPlayers[k].playersTeam << ' ' << allPlayers[k].playerValue << '\n';
    }
    myfile.close();
    return 0;
}

目前没有问题。 然而,下一次用户尝试运行程序并使用更新后的玩家银行时,问题就出现了:他们之前输入银行但只有名字的任何新玩家都不会从 txt 文件中提取,因为我提取了值如下:

std::istream& operator>> (std::istream& input, playerData& data)
{
    std::string first;
    std::string last;;
    input >> first >> last;
    input >> data.playerPosition;
    input >> data.playersTeam;
    input >> data.playerValue;
    data.playerName = first + ' ' + last;
    return input;
}

std::vector<playerData> createPlayerBankFromFile()
{
    std::vector<playerData> playerBank{};
    playerData playerStruct;
    std::ifstream inFile;
    inFile.open("playerbank.txt");
    while (inFile >> playerStruct)
    {
        playerBank.push_back(playerStruct);
    }
    inFile.close();
    return playerBank;
}

问题当然是我试图提取两个字符串,但是当它遇到一个新的播放器结构时只有 1 个,用户添加到播放器库中只有一个名字。 在我看来,一个简单的解决方案是编写一个循环以确保用户在创建新玩家时同时输入名字和姓氏,但我该怎么做呢? 我可以做两条提取线,例如:

std::string first;
std::string last;
std::cout << "Enter player's first name: ";
std::getline(std::cin, first);
std::cout << "Enter the player's last name: ";
std::getline(std::cin, last);

然后连接字符串以生成完整的玩家名称,但我想提示用户一次并在一行中获取完整的玩家名称。

您假设人们只有 1 个名字和 1 个姓氏,由 1 个空格分隔。 名字并不总是那么简单。

您应该提示用户输入 1 个字符串,将其保存到playerName ,然后将整个playerName按原样存储到您的文件中,后跟一个保证永远不会出现在任何名称中的分隔符,无论是换行符还是任何您想要的其他字符(空格除外),例如:

myfile.open("playerbank.txt");
for (int k = 0; k < allPlayers.size(); ++k)
{
    myfile << allPlayers[k].playerName << '|' << ... << '\n';
}
myfile.close();

然后,当从文件中读回名称时,您可以使用std::getline()直接读入playerName (完全摆脱firstlast ),直到达到您选择的分隔符,例如:

#include <limits>

std::istream& operator>> (std::istream& input, playerData& data)
{
    // read until the delimiter is reached...
    std::getline(input, data.playerName, '|');

    // read the other values from input as needed...

    // don't forget to read and discard the trailing line break at the end!
    input.ignore(std::numeric_limits<std::streamsize>::max(), '\n');

    return input;
}

或者:

#include <sstream>

std::istream& operator>> (std::istream& input, playerData& data)
{
    std::string line;
    if (!std::getline(input, line)) //<-- handles the trailing line break for you
        return input;

    std::istringstream iss(line);

    // read until the delimiter is reached...
    std::getline(iss, data.playerName, '|');

    // read the other values from iss as needed...

    return input;
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM