使用 YAML-CPP 发出解析文件
在下面的代码中,我在使用 parser.GetNextDocument(doc);
解析 .yaml 文件时遇到了某种问题。经过大量调试后,我发现这里的(主要)问题是我的 for 循环没有运行,因为 doc.size() == 0;
我做错了什么?
void
BookView::load()
{
aBook.clear();
QString fileName =
QFileDialog::getOpenFileName(this, tr("Load Address Book"),
"", tr("Address Book (*.yaml);;All Files (*)"));
if(fileName.isEmpty())
{
return;
}
else
{
try
{
std::ifstream fin(fileName.toStdString().c_str());
YAML::Parser parser(fin);
YAML::Node doc;
std::map< std::string, std::string > entry;
parser.GetNextDocument(doc);
std::cout << doc.size();
for( YAML::Iterator it = doc.begin(); it != doc.end(); it++ )
{
*it >> entry;
aBook.push_back(entry);
}
}
catch(YAML::ParserException &e)
{
std::cout << "YAML Exception caught: "
<< e.what()
<< std::endl;
}
}
updateLayout( Navigating );
}
正在读取的 .yaml 文件是使用 yaml-cpp 生成的,因此我假设它是正确形成的 YAML,但为了以防万一,这里还是该文件。
^@^@^@\230---
-
address: ******************
comment: None.
email: andrew(dot)levenson(at)gmail(dot)com
name: Andrew Levenson
phone: **********^@
编辑:根据请求,发出代码:
void
BookView::save()
{
QString fileName =
QFileDialog::getSaveFileName(this, tr("Save Address Book"), "",
tr("Address Book (*.yaml);;All Files (*)"));
if (fileName.isEmpty())
{
return;
}
else
{
QFile file(fileName);
if(!file.open(QIODevice::WriteOnly))
{
QMessageBox::information(this, tr("Unable to open file"),
file.errorString());
return;
}
std::vector< std::map< std::string, std::string > >::iterator itr;
std::map< std::string, std::string >::iterator mItr;
YAML::Emitter yaml;
yaml << YAML::BeginSeq;
for( itr = aBook.begin(); itr < aBook.end(); itr++ )
{
yaml << YAML::BeginMap;
for( mItr = (*itr).begin(); mItr != (*itr).end(); mItr++ )
{
yaml << YAML::Key << (*mItr).first << YAML::Value << (*mItr).second;
}
yaml << YAML::EndMap;
}
yaml << YAML::EndSeq;
QDataStream out(&file);
out.setVersion(QDataStream::Qt_4_5);
out << yaml.c_str();
}
}
In the following code, I'm having some sort of issue getting my .yaml file parsed using parser.GetNextDocument(doc);
. After much gross debugging, I've found that the (main) issue here is that my for loop is not running, due to doc.size() == 0;
What am I doing wrong?
void
BookView::load()
{
aBook.clear();
QString fileName =
QFileDialog::getOpenFileName(this, tr("Load Address Book"),
"", tr("Address Book (*.yaml);;All Files (*)"));
if(fileName.isEmpty())
{
return;
}
else
{
try
{
std::ifstream fin(fileName.toStdString().c_str());
YAML::Parser parser(fin);
YAML::Node doc;
std::map< std::string, std::string > entry;
parser.GetNextDocument(doc);
std::cout << doc.size();
for( YAML::Iterator it = doc.begin(); it != doc.end(); it++ )
{
*it >> entry;
aBook.push_back(entry);
}
}
catch(YAML::ParserException &e)
{
std::cout << "YAML Exception caught: "
<< e.what()
<< std::endl;
}
}
updateLayout( Navigating );
}
The .yaml file being read was generated using yaml-cpp, so I assume it is correctly formed YAML, but just in case, here's the file anyways.
^@^@^@\230---
-
address: ******************
comment: None.
email: andrew(dot)levenson(at)gmail(dot)com
name: Andrew Levenson
phone: **********^@
Edit: By request, the emitting code:
void
BookView::save()
{
QString fileName =
QFileDialog::getSaveFileName(this, tr("Save Address Book"), "",
tr("Address Book (*.yaml);;All Files (*)"));
if (fileName.isEmpty())
{
return;
}
else
{
QFile file(fileName);
if(!file.open(QIODevice::WriteOnly))
{
QMessageBox::information(this, tr("Unable to open file"),
file.errorString());
return;
}
std::vector< std::map< std::string, std::string > >::iterator itr;
std::map< std::string, std::string >::iterator mItr;
YAML::Emitter yaml;
yaml << YAML::BeginSeq;
for( itr = aBook.begin(); itr < aBook.end(); itr++ )
{
yaml << YAML::BeginMap;
for( mItr = (*itr).begin(); mItr != (*itr).end(); mItr++ )
{
yaml << YAML::Key << (*mItr).first << YAML::Value << (*mItr).second;
}
yaml << YAML::EndMap;
}
yaml << YAML::EndSeq;
QDataStream out(&file);
out.setVersion(QDataStream::Qt_4_5);
out << yaml.c_str();
}
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
按照您的想法,问题在于您使用 QDataStream 编写,但使用普通的 std::ifstream 读取。您需要选择其中之一。
如果您想使用
QDataStream
,您还需要读入它。查看 doc 了解更多详细信息,但看起来您可以直接获取YAML 字符串:然后将其传递给 yaml-cpp:
std::stringstream
的要点是将包含 YAML 的字符串转换为 YAML 解析器可以读取的流。Along the lines of what you thought, the problem is that you're writing using
QDataStream
but reading using plainstd::ifstream
. You need to do either one or the other.If you want to use the
QDataStream
, you'll need to read it in as well. Check out the doc for more detail, but it looks like you can just grab the YAML string:and then pass it to yaml-cpp:
The point of a
std::stringstream
is to transform your string containing YAML into a stream that the YAML parser can read.