[英]How to ensure user inputs a first and last name when only prompting for input once on one line?
C++ beginner here. C++ 初学者在这里。 I am storing structs of playerData in a vector (referred to as the player bank).我将 playerData 的结构存储在一个向量中(称为播放器库)。 One member of the struct is the player's name (stored in the struct as 1 string like "Julio Jones").该结构的一个成员是玩家的名字(在结构中存储为 1 个字符串,如“Julio Jones”)。 While using my application, if the user inputs a name that is not in my program's premade bank of players, the user is prompted to add the new name to the player bank for future use.在使用我的应用程序时,如果用户输入的名称不在我程序的预制播放器库中,系统会提示用户将新名称添加到播放器库以供将来使用。 The name input code is:名称输入代码为:
std::string input{};
std::cout << "Enter the player " << m_name << " traded: ";
std::getline(std::cin, input);
At the end of using the program, the user can save any changes they have made to the player bank for future use.在使用程序结束时,用户可以保存他们对播放器库所做的任何更改以备将来使用。 I did so by writing the vector to a txt file我通过将矢量写入 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;
}
There are no issues at this point.目前没有问题。 However, the issue arises the next time the user tries to run the program and use their updated player bank: any new player they had previously entered into the bank that only had a first name will not be extracted from the txt file because I extract the values as follows:然而,下一次用户尝试运行程序并使用更新后的玩家银行时,问题就出现了:他们之前输入银行但只有名字的任何新玩家都不会从 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;
}
The issue is of course that I am trying to extract two strings, but there is only 1 when it encounters a new player struct that the user added to the player bank with only a first name.问题当然是我试图提取两个字符串,但是当它遇到一个新的播放器结构时只有 1 个,用户添加到播放器库中只有一个名字。 It seems to me that an easy solution to this would be to write a loop to ensure that the user inputs both a first and last name when creating new players, but how can I do so?在我看来,一个简单的解决方案是编写一个循环以确保用户在创建新玩家时同时输入名字和姓氏,但我该怎么做呢? I could do two extraction lines like:我可以做两条提取线,例如:
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);
then concatenate the strings to make the full player name, but I'd like to prompt the user once and get the full player name in one line.然后连接字符串以生成完整的玩家名称,但我想提示用户一次并在一行中获取完整的玩家名称。
You are assuming that people have only 1 first name and 1 last name separated by 1 space.您假设人们只有 1 个名字和 1 个姓氏,由 1 个空格分隔。 Names are not always that simple.名字并不总是那么简单。
You should prompt the user for 1 string, save that to the playerName
, and then store the entire playerName
as-is to your file followed by a delimiter that is guaranteed to never appear in any name, whether that be a line break, or any other character you want (other than space), eg:您应该提示用户输入 1 个字符串,将其保存到playerName
,然后将整个playerName
按原样存储到您的文件中,后跟一个保证永远不会出现在任何名称中的分隔符,无论是换行符还是任何您想要的其他字符(空格除外),例如:
myfile.open("playerbank.txt");
for (int k = 0; k < allPlayers.size(); ++k)
{
myfile << allPlayers[k].playerName << '|' << ... << '\n';
}
myfile.close();
Then, when reading back a name from the file, you can use std::getline()
to read directly into playerName
(get rid of first
and last
completely) until your chosen delimiter is reached, eg:然后,当从文件中读回名称时,您可以使用std::getline()
直接读入playerName
(完全摆脱first
和last
),直到达到您选择的分隔符,例如:
#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;
}
Alternatively:或者:
#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.