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

Read one string from text file and store in multiple variables c++

本文关键字:串并 字符串 存储 c++ 变量 字符 文件 文本 读取 一个      更新时间:2023-10-16

所以我正在为学校做一个项目。我正在制作游戏"柠檬水看台"作为一个基于文本的主机游戏。从保存文件读取数据并将其存储在适当的位置时遇到问题。问题是,我们将所有数据输出到一个文本文件中,然后在该文本文件中将其分解为多行。我想一次读取一行文件,并将字符串的内容吐回变量中。这将需要一些变量转换,我也需要帮助。

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();
    }
}

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

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

我将比David Fang的回答更进一步,演示一些基本的错误检查和读取后的播放器存储。

注意:入门代码取自这类问题的半官方答案,逐行阅读文件。

#include <sstream>
#include <string>
#include <vector>

需要一些包括这个功能

std::vector<Player> loadGame()

定义一个函数,将文件中的所有玩家数据加载到std::vector中。为什么是矢量?如果游戏有多个玩家,我们必须把他们放在某个地方,而vector在某个位置是非常容易的。

{
    std::vector<Player> players; 
    std::string line;
    while (std::getline(infile, line))  

读入一行,如果没有行就退出。getline文档。

    {
        std::string playerName;
        int funds, supplies, turn;
        std::istringstream iss(line); 

将该行加载到易于解析的流中。使用与cin或infile 完全相同

        if (iss >> playerName >> funds >> supplies >> turn) 

在线上读取所有预期输入。如果有任何错误,请跳到else案例进行清理。注意:不处理线路上的意外输入。我们在这里读取所有输入,而不是稍后读取,因为如果输入不好,那么构建Player就没有意义。

如果无法读取任何变量并将其转换为正确的类型,则流将被设置为错误状态。if将检查此状态,就像您调用good()一样。如果输入良好,我们可以设置Player对构造函数的一次调用,而不是对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;
}