c – 读出一个stringstream并将其插入不同的vectores

(对不起,如果我问这个问题错了,这是我第一次在论坛上写)

当我开始编程我的SFML – Game时,我有一本非常古老的书,它非常像C(例如atoi()的推荐;).
现在我得到了一本新的C(包括C 11)书,我想用新的Code重写旧行.

我将Tiles保存在这样存储的文件中:

[0-0,15-1|22,44] [0-1|0]
[4-0,10-1,3-1|0] [0-5,5-5|0]

这意味着:
[…] desribes a Tile
0-0等是纹理表上的xy位置
22等是将被触发的事件.
事件的数量和sf :: Vector2i不应该不断设置.

Tiles分别从另一个类中取出,该类管理整个Tilemap.

现在我的问题:我不知道我应该如何从两个vectores中的strinstream推送数字?
我的代码:

class Tile{
     private:
          std::deque<sf::Sprite> tile;
      std::deque<int> event;
     public:

    Tile(sf::Texture& texture, std::deque<sf::Vector2i>&& ctor_texturerects, std::deque<int>&& ctor_events);//This one is working fine

    Tile(sf::Texture& texture, std::stringstream&& ctor_stream/*reads the Tile*/){

      std::deque<sf::Vector2i> temp_texturerects;
      std::deque<int>temp_events;
      /*TODO: filter the stringstream and push them into the containers*/
      Tile::Tile(texture,std::move(temp_texturerect),std::move(temp_events));
}

如果你能给我另一个解决方案,比如将sf :: Vector2i改成更好的解决方案或者给我一个更好的流和类概念,我也会非常高兴
提前致谢
Xeno Ceph

编辑:
我做了一点解决方法:
(我将输入流更改为普通字符串)
但是代码看起来不太好
最简单的解决方案

Tile::  Tile(sf::Texture& texture, std::string&& ctor_string){
    std::deque<sf::Vector2i> temp_texturerects;
    std::deque<int> temp_events;
    std::stringstream strstr;


    for(int i=0; i<ctor_string.size(); ++i){
        while(ctor_string[i]!='|'){

            while(ctor_string[i] != ','){
                strstr << ctor_string[i];
            }
            sf::Vector2i v2i;
            strstr >> v2i.x >> v2i.y;
            temp_texturerects.push_front(v2i);
            strstr.str("");
        }
        while(ctor_string[i]!=']'){
            while(ctor_string[i] != ','){
                strstr << ctor_string[i];
            }
            int integer;
            strstr  >> integer;
            temp_events.push_front(integer);
            strstr.str("");
        }
    }
    Tile::Tile(texture, std::move(temp_texturerects), std::move(temp_events));
} 

有人有更好的解决方案吗?

最佳答案 如果我正确理解你的问题,你就会有一些形式的字符串

[0-0,15-1|22,44] [0-1|0]
[4-0,10-1,3-1|0] [0-5,5-5|0]

并且您想要提取2种类型的数据 – 位置(例如0-0)和事件(例如22).
您的问题是如何干净地提取这些数据,丢弃[和]字符等.

解决这个问题的一个好方法是使用对字符串流进行操作的getline函数,该函数继承自std :: istream(http://www.cplusplus.com/reference/string/string/getline/).它可以采用自定义分隔符,而不仅仅是换行符.所以你可以使用'[‘,’|’和’]’作为不同的分隔字符并按逻辑顺序解析它们.

例如,由于您的字符串只是一个tile集合,您可以将它拆分为许多函数 – ParseTile,ParsePositions和ParseEvents,如下所示:

void Tile::ParseInput(stringstream&& ctor_string) {

  //extract input, tile by tile
  while(!ctor_string.eof()) {
    string tile;

    //you can treat each tile as though it is on a separate line by
    //specifying the ']' character as the delimiter for the "line"
    getline(ctor_string, tile, ']');
    tile += "]"; //add back the ']' character that was discarded from the getline

    //the string "tile" should now contain a single tile [...], which we can further process using ParseTile
    ParseTile(tile);
  }

}

ParseTile函数:

void Tile::ParseTile(string&& tile) {
  //input string tile is e.g. " [0-0, 15-1|22,44]"

  string discard; //string to hold parts of tile string that should be thrown away
  string positions; //string to hold list of positions, separated by ','
  string events; //string to hold events, separated by ','

  //create stringstream from input
  stringstream tilestream(tile);
  //tilestream is e.g. "[0-0,15-1|22,44]"

  getline(tilestream, discard, '['); //gets everything until '['
  //now, discard is " [" and tilestream is "0-0,15-1|22,44]"

  getline(tilestream, positions, '|');
  //now, positions is "0-0,15-1" and tilestream is "22,44]"

  getline(tilestream, events,']');
  //now, events is "22,44" and tilestream is empty

  ParsePositions(positions);

  ParseEvents(events);


}

您可以编写自己的ParsePositions和ParseEvents函数,这些函数基本上是一个更多的getline调用,使用’,’作为分隔符(只是循环直到字符串结束).

点赞