【问题标题】:Assigning Variables from CSV files (or another format) in C++在 C++ 中从 CSV 文件(或其他格式)分配变量
【发布时间】:2012-05-06 14:23:41
【问题描述】:

你好 Stack Overflow 世界:3 我的名字是 Chris,我有一个小问题.. 所以我将以这种格式提出这个问题.. 第 1 部分 我将介绍我目前正在使用的材料和代码 sn-ps 正在工作.. 第 2 部分 我将尽我所能解释我想要实现目标的新方法。 第 3 部分 所以你们认为我没有让你们做所有的工作,我会继续介绍我在上述目标上的尝试,以及研究可能发现的我不完全理解的方式。

第 1 部分

mobDB.csv 示例:

ID      Sprite    kName     iName     LV  HP    SP  EXP JEXP Range1 ATK1 ATK2   DEF MDEF  STR   AGI VIT INT DEX LUK Range2  Range3  Scale   Race    Element Mode    Speed   aDelay  aMotion dMotion MEXP    ExpPer  MVP1id  MVP1per MVP2id  MVP2per MVP3id  MVP3per Drop1id Drop1per    Drop2id Drop2per    Drop3id Drop3per    Drop4id Drop4per    Drop5id Drop5per    Drop6id Drop6per    Drop7id Drop7per    Drop8id Drop8per    Drop9id Drop9per    DropCardid  DropCardper
1001    SCORPION  Scorpion  Scorpion  24  1109  0   287 176  1      80   135    30  0     1     24  24  5   52  5   10      12      0       4       23      12693   200     1564    864     576     0       0       0       0       0       0       0       0       990     70          904     5500        757     57          943     210         7041    100         508     200         625     20          0       0           0       0           4068        1
1002    PORING    Poring    Poring    1   50    0   2   1    1      7    10     0   5     1     1   1   0   6   30  10      12      1       3       21      131     400     1872    672     480     0       0       0       0       0       0       0       0       909     7000        1202    100         938     400         512     1000        713     1500        512     150         619     20          0       0           0       0           4001        1
1004    HORNET    Hornet    Hornet    8   169   0   19  15   1      22   27     5   5     6     20  8   10  17  5   10      12      0       4       24      4489    150     1292    792     216     0       0       0       0       0       0       0       0       992     80          939     9000        909     3500        1208    15          511     350         518     150         0       0           0       0           0       0           4019        1
1005    FARMILIAR Familiar  Familiar  8   155   0   28  15   1      20   28     0   0     1     12  8   5   28  0   10      12      0       2       27      14469   150     1276    576     384     0       0       0       0       0       0       0       0       913     5500        1105    20          2209    15          601     50          514     100         507     700         645     50          0       0           0       0           4020        1
1007    FABRE     Fabre     Fabre     2   63    0   3   2    1      8    11     0   0     1     2   4   0   7   5   10      12      0       4       22      385     400     1672    672     480     0       0       0       0       0       0       0       0       914     6500        949     500         1502    80          721     5           511     700         705     1000        1501    200         0       0           0       0           4002        1
1008    PUPA      Pupa      Pupa      2   427   0   2   4    0      1    2      0   20    1     1   1   0   1   20  10      12      0       4       22      256     1000    1001    1       1       0       0       0       0       0       0       0       0       1010    80          915     5500        938     600         2102    2           935     1000        938     600         1002    200         0       0           0       0           4003        1
1009    CONDOR    Condor    Condor    5   92    0   6   5    1      11   14     0   0     1     13  5   0   13  10  10      12      1       2       24      4233    150     1148    648     480     0       0       0       0       0       0       0       0       917     9000        1702    150         715     80          1750    5500        517     400         916     2000        582     600         0       0           0       0           4015        1
1010    WILOW     Willow    Willow    4   95    0   5   4    1      9    12     5   15    1     4   8   30  9   10  10      12      1       3       22      129     200     1672    672     432     0       0       0       0       0       0       0       0       902     9000        1019    100         907     1500        516     700         1068    3500        1067    2000        1066    1000        0       0           0       0           4010        1
1011    CHONCHON  Chonchon  Chonchon  4   67    0   5   4    1      10   13     10  0     1     10  4   5   12  2   10      12      0       4       24      385     200     1076    576     480     0       0       0       0       0       0       0       0       998     50          935     6500        909     1500        1205    55          601     100         742     5           1002    150         0       0           0       0           4009        1

所以这是我拥有的电子表格的一个示例。这是我希望在我的理想目标中使用的。不是我现在使用的。它是在 MS Excel 2010 中完成的,使用 A-BF 列和 1-993 行

目前我的工作代码格式,我正在使用手动实现的数组。例如,对于我拥有的 iName:

char iName[16][25] = {"Scorpion", "Poring", "Hornet", "Familiar", "null", "null", "null", "null", "null", "null", "null", "null", "null", "null", "null", "null"};

现在在头文件 (bSystem.h) 中定义以应用,可以说他们的健康变量?我必须在同一个 Header 中有另一个具有相应顺序的数组,如下所示:

int HP[16] = {1109, 50, 169, 155, 95, 95, 118, 118, 142, 142, 167, 167, 193, 193, 220, 220};

问题是,有大量数据要硬编码到我需要的各种文件中,用于怪物、物品、法术、技能等。在最初的小规模上获得某些系统就很好了。我一直在头文件中使用各种 Void 在调用时将数据从文件传输到文件。但是当我处理 1,000 多个怪物并且不得不使用所有这些变量时。手动将它们放入有点......荒谬?哈哈……

第 2 部分

现在我的理想系统是能够使用 .CSV 文件来加载数据。我在这项任务中遇到了相当多的各种问题。例如,将从 Names 中提取的数据转换为一个 Char 数组,实际上是从 CSV 文件中提取数据并将特定部分分配给某些数组......我的主要想法是,我似乎无法理解;

我希望能够找到一种方法来从 CSV 文件中读取这些不同的变量...所以当我调用如下变量时:

cout << name << "(" << health << " health) VS. " << iName[enemy] << "(" << HP[enemy] << " health)";

[enemy] 所在的位置是 ID.. 敌人的遭遇在另一个标题 (lSystem.h) 中,它基本上是这样的;

case 0:
        enemy = 0;

其中 0 将是涉及怪物的数组中的第一个数据。我讨厌它必须是特定于顺序的。我希望能够说敌人 = 1002;因此,当战斗系统启动时,它可以从 ID 为 1002 的敌人那里提取所需的变量..

我总是遇到一些不同的问题,我无法将数据从文件中提取到程序中。当我可以时,我只能让它将 int 值存储到 int 数组中,我遇到了问题它将字符串转换为 char 数组。然后我遇到的下一个问题是回忆它和实际保存的部分......这就是第 3 部分的用武之地:3

第三部分

到目前为止,我已经尝试了一些不同的事情,并研究了如何实现这一目标..到目前为止我遇到的是..

我可以编写一个函数来读取 mobDB 中的数据,将其记录到数组中,然后将其输出到 .dat?因此,当我需要调用变量时,我可以从 .dat 而不是可修改的 CSV 中做一些事情。就阅读和转换而言,我遇到了同样的问题。

我可以走 SQL 路线,但我在理解如何从 SQL 中提取数据时遇到了很多问题?我家里有一个 PowerEdge 2003 服务器盒,我在上面存储数据,它确实设置了 NavicatSQL Premium,所以我想我关于 SQL 路由的主要 2 个问题是,是否可以直接连接到 SQLServer 并且当我更新时数据库,当客户端运行时,它只会从数据库中提取变量和数据?或者我会被困在编译 SQL 文件...当它是一个在线游戏时,我知道我将不得不使用一些东西从服务器传输到客户端,这就是为什么我试图在开发早期设置它所以我有更多建立起来,我确定我可以使用 SQL 服务器吗?如果有人对它的工作原理有很好的了解,我非常想走 SQL 路线..

我所做的尝试是使用 Boost 来解析来自 CSV 而不是标准库的数据。出现了同样的问题。我确实阅读了将字符串转换为字符的内容。但问题出在一次拉取数据,无法转换?..

我也尝试过 ADO C++ 路线..死路一条..

总而言之,我在过去一周左右的时间里都花在这上面。我非常想设置 SQL 服务器来实际更新变量……但我愿意接受任何易于编辑的工作想法并实现大量数据..

感谢所有帮助。如果有人确实试图帮助获得一个工作代码,如果将 cmets 添加到您认为应该解释的部分不是太麻烦?我不希望有人只是给我一个快速修复..我实际上想学习和了解我正在使用什么。非常感谢大家:)

-克里斯

【问题讨论】:

  • 感谢您尝试解释这种情况。你只是在一个问题上太多了。您确实需要将其范围缩小到您遇到的一个特定问题。
  • @VaughnCato 我想如果有的话,我的唯一问题是......我怎样才能从 SQL 服务器中提取所需的信息和各种变量?如果这有意义的话。
  • 对于初学者,你知道std::stringstd::vector吗?

标签: c++ sql arrays visual-studio computer-science


【解决方案1】:

让我们看看我是否正确理解了您的问题:您正在编写一个游戏,目前您的游戏演员的所有统计数据都是硬编码的。您已经有一个包含此数据的 Excel 电子表格,并且您只想使用它而不是硬编码的头文件,这样您就可以调整统计数据而无需等待长时间的重新编译。您当前以列存储方式将统计信息存储在代码中,即每个属性一个数组。 CSV 文件以逐行方式存储内容。到目前为止正确吗?

现在我对您的问题的理解变得有些模糊。但是让我们尝试一下。如果我理解正确,您想从代码中完全删除数组并在需要某些生物的统计数据时直接访问 CSV 文件?如果是,那么这已经是问题所在了。文件 I/O 非常慢,您需要将这些数据保存在主内存中。只需保留数组,而不是手动分配标题中的值,您有一个加载函数,当您开始游戏时读取 CSV 文件并将其内容加载到数组中。您可以保持其余代码不变。

例子:

void load (std::ifstream &csv)
{
    readFirstLineAndCheckThatItIsCorrect (csv);

    while (!csv.eof())
    {
        int id;
        std::string spriteName;

        csv >> id;
        csv >> spriteName >> kName[id] >> iName[id] >> LV[id] >> HP[id] >> SP[id] >> ...

        Sprite[id] = getSpriteForName (spriteName);
    }
}

使用数据库系统完全超出了这里的范围。您需要做的就是将一些数据加载到一些数组中。如果您希望能够在不重新启动程序的情况下更改统计信息,请添加一些热键以重新加载 CSV 文件。

如果您打算编写一款在线游戏,那么您还有很长的路要走。即使这样,SQL 对于在服务器和客户端之间交换数据也是一个非常糟糕的主意,因为 a) 它只是引入了太多的开销 b) 它是对作弊者和黑客的公开邀请,因为如果客户端可以直接访问您的数据库,您可以不再验证他们的输入。有关实际示例,请参阅http://forums.somethingawful.com/showthread.php?noseen=0&pagenumber=258&threadid=2803713。 如果你真的想让它成为一个网络游戏,你需要设计你自己的通信协议。但也许你应该先读一些关于这方面的书,因为这确实是一个复杂的问题。例如,您需要通过在客户端猜测服务器和其他玩家接下来最有可能做什么来向用户隐藏延迟,并在错误时优雅地纠正您的猜测,所有这些都不会让玩家注意到(航位推算) .

不过,祝你的游戏好运,我希望有一天能玩上它。 :-)

【讨论】:

  • 你说得对,在它上线之前我还有很长的路要走......是的,理想的我希望能够更新 CSV 中的值,并在加载时获取信息从CSV并适当地保存它,我只是不知道如何将它保存到一个数组:(
  • 你已经有了数组。您只需要更改用数据填充它们的方式。我添加了一些示例代码,现在可能更清楚了。
  • 啊,我明白了。我想我明白了!我会就我的进展与您联系。
  • 我将在哪里定义'readFirstLineAndCheckThatItIsCorrect' 我还看到 csv >> 中的运算符编译时会出现错误,没有匹配项?而且我还必须定义 getSpriteForName (spriteName);如果这看起来很愚蠢,我很抱歉。我从来没有做过这种事情,想确保我做对了,你知道吗?但到目前为止我还了解其他的。
  • 修复了所有内容,除了定义“readFirstLineAndCheckThatItIsCorrect”和“getSpriteForName”我还不确定这些实际上做了什么。
【解决方案2】:

IMO,最简单的做法是首先创建一个包含怪物所有数据的结构。这是一个简化版本,因为我不想输入所有这些变量。

struct Mob
{
    std::string SPRITE, kName, iName;
    int ID, LV, HP, SP, EXP;
};

您的特定格式的加载代码非常简单:

bool ParseMob(const std::string & str, Mob & m)
{
    std::stringstream iss(str);
    Mob tmp;
    if (iss >> tmp.ID >> tmp.SPRITE >> tmp.kName >> tmp.iName
            >> tmp.LV >> tmp.HP >> tmp.SP >> tmp.EXP)
    {
        m = tmp;
        return true;
    }
   return false;
}

std::vector<Mob> LoadMobs()
{
    std::vector<Mob> mobs;
    Mob tmp;
    std::ifstream fin("mobDB.csv");
    for (std::string line; std::getline(fin, line); )
    {
        if (ParseMob(line,tmp))
            mobs.emplace_back(std::move(tmp));
    }
    return mobs;
}

【讨论】:

  • 我想我已经了解了这个的基本概念。如果你能更详细地了解如何在这一点之后调用数据,以及如何实现这一点,我不想犯任何错误并迷惑自己。
  • (我目前正在修改它以支持所有变量)
  • @ChrisRiley:你知道如何使用std::vector吗?如果没有,那么您需要阅读an introductory book on C++。或者你可以阅读documentation
  • 是的,我有一个相当不错的,我愿意相信,对vector的理解
  • @ChrisRiley:那么你在理解如何调用数据方面有什么困难?
猜你喜欢
  • 2014-10-26
  • 1970-01-01
  • 2011-02-16
  • 1970-01-01
  • 2018-05-31
  • 2021-12-27
  • 1970-01-01
  • 2017-09-15
  • 1970-01-01
相关资源
最近更新 更多