如何在特定位置追加 json 文件

How to append in json file at specific position

本文关键字:追加 json 文件 位置 定位      更新时间:2023-10-16

我正在尝试将 JSON 对象附加到特定位置的文件,但我无法按要求执行此操作。我得到结果但没有","分隔值,因此它们是单独的 JSON 对象。

我想遍历 JSON 对象并将结果附加到文件中并用","分隔它,它是一个有效的 JSON。这是我尝试过的


auto js_text = R"(
{
"a": "all_items",
"b": []
}
)";
std::ofstream js_file("test.json");
js_file << std::setw(4) << js_text << std::endl;
std::ifstream in("test4.json");
json js_file = json::parse(in);
std::ifstream load_url("url_file.json");
json url_file = json::parse(load_url);
for (auto& endpoint : url_file["url_list"])
{
std::string url = endpoint["url"].get<std::string>(); 
auto r = cpr::Get(cpr::Url{ url }); 
json j = json::parse(r.text); // r gets a nested json objects from parsed url
for (auto& td : j["b"])    
{    
json value = j["b"][0];
json data = js_file;
data["b"][0] = value;
std::ofstream output;
output.open("test.json",std::ios_base::app );
output << std::setw(4) << data << std::endl;
}

我想要的结果是

{
"a": "all_items",
"b": [
{
"c": "xxx",
"d": "yyy"
},
{
"e": "zzz"
}
]
}

更新代码:在 Botje 有价值的输入之后。

auto js_text = R"(
{
"a": "abc",
"b": [ ]
}
)";
json js_file = json::parse(js_text);
std::ifstream load_url("url_file.json");
json url_file = json::parse(load_url);
for (auto& endpoint : url_file["url_list"])
{
std::string url = endpoint["url"].get<std::string>(); 
auto r = cpr::Get(cpr::Url{ url }); 
json j = json::parse(r.text); // j contains results from multiple HTTP requests that has json objects.
for (auto& elem : j["b"])
{
json jd = j["b"];
js_file["b"].emplace_back(std::move(td));
std::cout << "jd:" << jd.dump(4) << std::endl;
}
}
std::ofstream output;
output.open("test.json",std::ios_base::app );
output << std::setw(4) << js_file << std::endl;
}

希望这对其他人有所帮助。

据我了解您的问题,您希望发出多个HTTP请求并将每个响应的"b"键下的所有对象收集到一个数组中。

在这里,我们跳过 HTTP 部分,并假设r_texts的每个元素都是一个响应对象。

std::vector<std::string> r_texts = {
R"({
"b": [{
"c": "xxx",
"d": "yyy"
}]
})",
R"({
"b": [{
"e": "zzz"
}]
})",
};

这将生成所需的输出,然后:

auto js_text = R"(
{
"a": "abc",
"b": []
}
)";
int main() {
json js_file = json::parse(js_text);
for (auto& r_text: r_texts) {
// r_text is now the contents of one "HTTP response"
json j = json::parse(r_text);
// Loop over all objects inside the "b" key
for (auto & elem: j["b"]) {
// And use emplace_back+move to detach the object from `j`
// and move it to the back of `js_file["b"]`.
js_file["b"].emplace_back(std::move(elem));
}
}
std::ofstream output;
output.open("test.json",std::ios_base::app );
output << std::setw(4) << js_file << std::endl;
}

假设:

std::string original_string;  // Original file contents as a string
json original_json; // JSON value parsed from original_string
json updated_json;  // original_json but updated with new values

然后你得到这样的字符串表示形式:

std::string updated_string = updated_json.dump();

现在,一次比较两个字符串字符,直到得到差异。这是您可以写入文件新内容的偏移量。

size_t update_offset = 0;
for (size_t i = 0; i < original_string.size(); ++i) {
if (i < updated_string.size()) {
// Update is shorter than original, something is wrong
}
if (original_string[i] != updated_string[i]) {
update_offset = i;
break;
}
}

此时,update_offset将具有两个字符串之间的共同字节数;在此之后的所有内容都已更改。现在,我们打开原始文件,寻找此偏移量并写入字符串的其余部分。

std::ofstream output{"test.json", std::ofstream::out};
output.seekp(update_offset);
output << updated_string.substr(update_offset);
output.close();

上述序列可确保输出文件的内容是 JSON 数据的语法正确表示形式。