从文本文件中读取一个字符串并存储在多个变量c ++中

时间:2015-12-11 00:57:02

标签: c++

所以我正在为学校做一个项目。我正在制作游戏“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();
    }
}

我的想法是,现在这可能太难了,最好将每个变量存储在自己的文件中,只需从这些文件中单独读取而不必解析一个文件。任何提示或答案将不胜感激。

2 个答案:

答案 0 :(得分:3)

您可以尝试std::getlinestd::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;
}