我试图了解更多关于C ++的知识,并且我正在制作(非常简单的)2D地图编辑器。我目前有一个运行良好的系统,但我试图通过使用标签来改进。
我想要完成的事情
我希望能够加载一个文本文件,并将它存储在一个级别中可能需要的所有数据(包括但不限于:磁贴,背景,对象,播放器等)。这些文本文件将由我的地图编辑器生成,因此我可以完全控制它们的创建方式和结构。 虽然这不是一个学校项目,但我试图了解更多关于C ++的知识,所以我宁愿使用尽可能少的依赖项(我目前只使用SFML,但是我不认为这与此相关),因此我没有使用现有的XML Parser。
//Call to my parser
getTagContents("Resources/xmltester.txt", "mytag");
//
void getTagContents(std::string fileToBeParsedLocation, std::string tagName)
{
int lineNumberToFindTagName = 0;
int lineNumberToFindTagNameEnd = 0;
std::vector<int> tagsLine;
std::vector<int> tagsPos;
std::vector<std::string> tagContents;
std::string tempLine;
std::fstream fileToBeParsed(fileToBeParsedLocation);
if (fileToBeParsed.is_open())
{
while (!fileToBeParsed.eof())
{
while (std::getline(fileToBeParsed, line))
{
//Opening tag
if (line.find("<" + tagName + ">") == -1)
{
lineNumberToFindTagName++;
}
else
{
std::size_t pos = line.find("<" + tagName + ">");
std::cout << "Found tag " << tagName << " opening at line " << lineNumberToFindTagName << " at position " << pos << std::endl;
tagsLine.push_back(lineNumberToFindTagName);
tagsPos.push_back(pos);
lineNumberToFindTagName++;
//Test
//std::getline(fileToBeParsed, tempLine);
//std::cout << tempLine;
//This returns really strange values
}
//Closing tag
if (line.find("</" + tagName + ">") == -1)
{
lineNumberToFindTagNameEnd++;
}
else
{
std::size_t pos = line.find("</" + tagName + ">");
std::cout << "Found tag " << tagName << " closing at line " << lineNumberToFindTagNameEnd << " at position " << pos << std::endl;
tagsLine.push_back(lineNumberToFindTagNameEnd);
tagsPos.push_back(pos);
lineNumberToFindTagNameEnd++;
}
}
}
//Size of tagContents will always be half of either tagsLine or tagsPos (it doesn't matter which)
for (int i = 0; i < tagsPos.size()/2; i++)
{
for (int j = 0; j < tagsLine[i]; j++)
{
//I think this is where most of the stuff I need to add should go
}
std::getline(fileToBeParsed, tempLine);
std::stringstream stream(tempLine);
std::cout << "Line contents: " << tempLine << "<>" << std::endl;
}
}
for (int i = 0; i < tagsPos.size(); i++)
{
std::cout << tagsLine[i] << "." << tagsPos[i] << std::endl;
}
getchar();
getchar();
}
问题是什么
这可能主要是由于我的无能,但我不知道如何使用我知道标签的事实。行和位置值,以便在它们之间进行读取。它应该是微不足道的,但我无法找到一种方法来确保我能正确读取任何数量的标签...
有什么想法吗? (并提前感谢)
答案 0 :(得分:0)
不要那样做。您正在尝试在不知道解析技术的情况下实现XML解析器。除了完全失败之外,这个项目永远不会结束。
你需要的是一个现有的XML解析器,它有两种变体,SAX样式解析按顺序读取文件,DOM样式解析将文件读入综合数据结构。
C(和C ++)最流行的SAX样式解析库是expat。我不确定它是否有面向对象的C ++包装器,但如果没有,如果你真的了解C ++,你可以用更少的时间来实现它,而不是自己的XML解析器。
如果需要DOM样式的解析,一个选项是处理SAX样式解析器中的事件并构造一个解析树。另一个选择是查看是否有任何DOM风格的C / C ++解析库。可能C ++库是一个更好的选择,因为DOM风格的库本质上是面向对象的,你确实想要为它们使用C ++语言的全部功能。
要了解有关解析XML的各种方法的更多信息,请参阅http://en.wikipedia.org/wiki/XML#Programming_interfaces
Simple API for XML意味着SAX和文档对象模型意味着DOM。
如果你真的想要实现自己的XML解析器,最好先研究现有技术(即基于SAX的解析和基于DOM的解析),然后决定你想要哪些解析器。你的原型解析器既不代表,也不是franky看起来不像是解析XML的成功方法。