(对不起,如果我问这个问题错了,这是我第一次在论坛上写)
当我开始编程我的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调用,使用’,’作为分隔符(只是循环直到字符串结束).