簡體   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