我的翻译文件如下:
#: this is just some comment
msgid ""
"this is a line.\n"
"this is a newline.\n"
"this is another newLine".
msgstr ""
"this can be filled in.\n"
"or left blank."
#: just another comment
msgid "Pizza"
msgstr ""
正如您所看到的,msgid
可以是多行或单行。同样适用于msgstr
。
我的所有翻译文件都是这样的。如何使用上面的数据示例创建一个包含两个键的json对象:
[
{
"msgid": "this is a line.\nthis is a newline.\nthis is another newLine.",
"msgstr": "this can be filled in.\n or left blank."
},
{
"msgid": "Pizza",
"msgstr": ""
}
]
我可以访问我知道如何使用的json库。我正在努力解决循环数据的for(each)循环。
目前我有这段代码:
std::ifstream input(findFile("language.po"));
Json::Value jsonRoot = Json:arrayValue;
for( std::string line; getline( input, line ); )
{
Json::Value Translation = Json::objectValue;
if(line.find("msgid") == 0) {
//messageId found
Translation["msgid"] = line;
} else if(line.find("msgstr") == 0) {
//translated string was found
Translation["msgstr"] = line;
}
jsonRoot.append(Translation);
}
然而,这为我不想要的每一行创建了一个新的json数组。
此时,当前输出(未测试)应如下所示:
[
{
"msgid": ""
},
{
"msgstr": ""
},
{
"msgid": "Pizza"
},
{
"msgstr": ""
}
]
答案 0 :(得分:1)
我会写一个简单的状态机:
enum class State { INIT, ID, STR } state = State::INIT;
std::string buffer;
while (!end_of_file()) {
auto s = get_next_line();
if (is_comment(s)) {
// do nothing
} else if (is_msgid(s)) {
if (state != State::STR) {
buffer += s; // depending on how you read a line, you may have to add EOL here
} else {
put_msgid_into_json(buffer);
buffer = s;
}
state = State::ID;
} else if (is_msgstr(s)) {
if (state != State::ID) {
buffer += s; // depending on how you read a line, you may have to add EOL here
} else {
put_msgstr_into_json(buffer);
buffer = s;
}
state = State::STR;
}
}
if (state == State::ID) {
put_msgid_into_json(buffer);
} else if (state == State::STR) {
put_msgstr_into_json(buffer);
}
答案 1 :(得分:1)
您的循环正在向阵列添加每一行,而不管每行的内容如何。你需要的是一个状态机,所以你只需要将完成的对象添加到数组中,你需要在前一行中添加延续行,直到你到达下一个字段开始,你需要解析这些行来删除行前缀和引号。 / p>
尝试更像这样的事情:
std::ifstream input(findFile("language.po").string());
std::string msgid, msgstr;
std::string *field = NULL;
std::string::size_type start, end;
Json::Value jsonRoot = Json::arrayValue;
for( std::string line; std::getline( input, line ); )
{
if (line.compare(0, 1, "#") == 0)
continue;
if (line.compare(0, 6, "msgid ") == 0)
{
if (!msgid.empty())
{
Json::Value Translation = Json::objectValue;
Translation["msgid"] = msgid;
Translation["msgstr"] = msgstr;
jsonRoot.append(Translation);
}
msgid.clear();
msgstr.clear();
field = &msgid;
start = 6;
}
else if (!field)
{
continue;
}
else if (line.compare(0, 7, "msgstr ") == 0)
{
field = &msgstr;
start = 7;
}
else
{
start = 0;
}
start = line.find('\"', start);
if (start == std::string::npos)
continue;
++start;
end = line.find('\"', start);
if (end != std::string::npos)
*field += line.substr(start, end-start);
else
*field += line.substr(start);
}
if (!msgid.empty())
{
Json::Value Translation = Json::objectValue;
Translation["msgid"] = msgid;
Translation["msgstr"] = msgstr;
jsonRoot.append(Translation);
}