Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/157.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 从语言文件创建JSON对象_C++_Json_File_C++11 - Fatal编程技术网

C++ 从语言文件创建JSON对象

C++ 从语言文件创建JSON对象,c++,json,file,c++11,C++,Json,File,C++11,我有一个翻译文件,如下所示: #: 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":

我有一个翻译文件,如下所示:

#: 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": ""
    },
    {
        "msgid": "Pizza"
    },
    {
        "msgstr": ""
    }
]
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);
}
如您所见,
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数组

此时,电流输出(未测试)应如下所示:

#: 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": ""
    },
    {
        "msgid": "Pizza"
    },
    {
        "msgstr": ""
    }
]
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);
}

我将编写一个简单的状态机:

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);
}

循环正在将每一行添加到数组中,而不考虑每一行的内容。您需要的是一个状态机,因此您只需将完成的对象添加到数组中,您需要将延续行附加到前面的行,直到到达下一个字段开始,并且您需要解析这些行以删除行前缀和引号

尝试类似以下内容:

#: 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": ""
    },
    {
        "msgid": "Pizza"
    },
    {
        "msgstr": ""
    }
]
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);
}

你能在你的问题中包括这个例程的当前输出状态吗?@Quirk我已经这样做了。现在打印的内容不多,因为我只检查字符串是否以
“msgid”
“msgstr”开头
您实际使用的JSON库是哪4行?我想OP正在使用。我正在使用ubuntuI上的包:
libjsoncpp dev
,请参见第5行缺少一个双精度的
,不知何故,我可能无法使用来自boost的findFile和ifstream<代码>错误:调用'std::basic_ifstream::basic_ifstream(boost::filesystem::path)时没有匹配的函数,我已经将
.c_str()
添加到路径中,它工作了:)因为ifstream需要字符串:)嗯,现在让我们查看结果:D@Baklap4:ifstream的
ifstream
声明是从您的示例复制的,您说该示例已经在运行,只是没有执行您想要的操作。在ycase中,你不是指代替
c_str()
?没有
c_str()
方法。虽然它使用
c_str()
@Baklap4:Nevermind编译和运行,但很奇怪,我正在查看旧的boost文档。我现在看到了最新的文档。