所以我正在为学校做一个项目。我正在制作游戏“Lemonade Stand”作为基于文本的控制台游戏。我无法从保存文件中读取数据并将其存储在适当的位置。问题是我们将所有数据输出到一个文本文件,然后在该文本文件中将其分成多行。我想一次读取一行文件并将字符串的内容吐回到变量中。这需要一些变量转换,我也需要帮助。
void loadGame(){
string playerName;
int funds, supplies, turn;
ifstream data ("data.lms");
if (data.is_open())
{
while ( data.good() )
{
if (data >> playerName)
Player.setPlayerName(playerName);
else
cout << "Couldn't read player name value.\n";
if (data >> funds)
Player.setFunds(funds);
else
cout << "Couldn't read funds value.\n";
if (data >> supplies)
Player.setSupplies(supplies);
else
cout << "Couldn't read supplies value.\n";
if (data >> turn)
Player.setTurn(turn);
else
cout << "Couldn't read turns value.\n";
}
data.close();
}
}
我的想法是,现在这可能太难了,最好将每个变量存储在自己的文件中,只需从这些文件中单独读取而不必解析一个文件。任何提示或答案将不胜感激。
答案 0 :(得分:3)
您可以尝试std::getline
和std::stringstream
。
首先包括sstream。
#include <sstream>
然后你可以逐行读取数据并分成字符串。
string line;
while(getline(data, line)) {
stringstream ss(line);
string name;
int funds, supplies, turns;
ss >> name >> supplies >> turns;
}
答案 1 :(得分:1)
我要比David Fang的答案更进一步,以便在阅读后展示一些基本的错误检查和存储。
注意:对于此类问题Read file line by line的半官方回答,起始代码已被取消。
#include <sstream>
#include <string>
#include <vector>
此功能需要一些包含
std::vector<Player> loadGame()
定义一个函数,将文件中的所有玩家数据加载到std::vector
。为什么是矢量?如果游戏中有多个玩家,我们必须把它们放在某个地方,而且矢量在某个地方很容易。
{
std::vector<Player> players;
std::string line;
while (std::getline(infile, line))
读入一行,如果没有行则退出。 getline
documentation.
{
std::string playerName;
int funds, supplies, turn;
std::istringstream iss(line);
将该行加载到an easily parsed stream。使用与cin或infile完全相同
if (iss >> playerName >> funds >> supplies >> turn)
在线读入所有预期输入。如果有任何错误,请跳过其他情况进行清理。注意:不会在线处理意外输入。我们在这里读取所有输入而不是稍后,因为如果输入不好,则无法构建Player
。
如果无法读取任何变量并将其转换为正确的类型,则流将设置为错误状态。 if会检查此状态,就像您调用good()
一样。如果输入是好的,我们可以在构造函数的一次调用中设置Player
all,而不是对setter进行一堆调用。这样,任何使用Player
的人都知道它已全部设置好并准备就绪,只是分配了。对于复杂的对象和多线程系统,这很重要。
Player
的名称也不会在游戏中途发生变化,因此名字的setter函数很狡猾。
{
Player player(playerName, funds, supplies, turn);
players.push_back(player);
制作Player
并将玩家置于向量中,或
players.emplace_back(playerName, funds, supplies, turn);
直接在矢量中设置Player
。
}
else
{
读取该行时发生了一个或多个错误。做你需要做的任何事情来处理错误
}
}
return players;
}
将加载的游戏返回给调用者。这看起来有点奇怪。我们通过值传递一个对调用者来说可能很大的列表。这可能意味着非常大且昂贵的复制操作。
幸运的是,编译器并不愚蠢。他们知道我们再也不会在这个函数中使用players
并且它是一个局部变量,因此一旦函数超出范围就会被销毁。编译器可以对向量执行任何操作,因为此向量实际上是死的。例如,它可以撕掉向量的内容,并将它们移植到调用者范围内的另一个向量中,而无需复制任何内容,并让数字乌鸦的向量吞噬。
该功能的用法是:
std::vector<Player> players = loadGame();
所有人都没有正在进行的评论:
#include <sstream>
#include <string>
#include <vector>
std::vector<Player> loadGame()
{
std::vector<Player> players;
std::string line;
while (std::getline(infile, line))
{
string playerName;
int funds, supplies, turn;
std::istringstream iss(line);
if (iss >> playerName >> funds >> supplies >> turn)
{
// Player player(playerName, funds, supplies, turn);
// players.push_back(player);
players.emplace_back(playerName, funds, supplies, turn);
}
else
{
// handle error
}
}
return players;
}