目前,我有多个 json 文件和一个 python 代码,它读取其中一个 json 文件 main.json,并根据 json 文件创建完整的 c++ 代码。在该 c++ 的 main() 中,我需要使用 numberToString.json 将数字输出转换为字符串。我找不到及时(<1 分钟)成功编译 c++ 代码的方法
我在 C++ 文件中创建了一个嵌套映射“std::map< std::string, std::map< std::string, std::string>> enumMap”,并填充了 numberToString.json 中的所有值(~20,000 个值),但代码没有及时编译(我在~5 分钟后将其关闭。CMAKE 使用 gcc 4.8.5 进行编译。)
示例代码:
main.json
{"example" : {
"FRUIT" : "ex_fruit"
},
...
}}
numberToString.json
{"FRUIT" : {
"1" : "fresh",
...,
"10" : "not fresh"
},
...
}}
someHeader.h
typedef struct FRUIT
{
int val;
};
typedef struct Example
{
FRUIT ex_fruit;
};
python.py
def someFunc(typename)
//input is struct name in string ex."Example"
"already implemented"
return memberVariables
//returns member variable accessors
print "#include \"someHeader.h\""
print "int main() {"
print " Example ex = {1};"
print " printf(%s, %s);" %("%s", someFunc("Example")
print "return 0;"
print "}"
pythonOutput.cxx
#include "someHeader.h"
int main() {
Example ex = {1};
printf(%s, ***ex.ex_fruit.val***);
return 0;
}
因此在 pythonOutput.cxx 上,我需要 ex.ex_fruit.val,即 1,以“新鲜” 通过使用 numberToString.json。
我使用的是python 2.7
最佳答案
您绝对不应该自动生成像那样硬编码 map 的 C++ 代码。有一些库可以将 json 文件直接读入 C++(例如参见 rapid json),应该改用这些库。代码的编译速度会快得多,读取 20,000 个文件所需的时间应该在几毫秒的数量级(而不是编译所需的 >5 分钟)。
如果您想避免在 C++ 代码中添加对 json 解析器的依赖,我建议将 JSON 文件转换为更简单的格式,这样更易于使用 C++ 读取。
从文件中读取和写入 map 的非常非常简单的格式
让我们来一张简单的 map :
map<string, map<string, string>> test_map {
{"Hello", {
{"A", "B"},
{"C", "D"}}},
{"World", {
{"Blarg", "glug glug glug"},
{"idek what to put here", "felt cute might delete later"}}}};
我们将使用非常简单的格式将其写入文件。字符串将写为 <string length> <string text>
, map 将写为 <map length> <map key-value pairs>
.因此,例如 "Hello world"
会写成 11 Hello world
.对于上面的 map ,对应的文件是
2 5 Hello2 1 A1 B1 C1 D5 World2 5 Blarg14 glug glug glug21 idek what to put here28 felt cute might delete later
你有 2,这意味着顶级 map 有 2 个元素。后面跟着一个 5,这意味着第一个键中有 5 个字符。接下来是第一个映射的键和值等。
以这种格式将映射写入文件
因为格式很简单,所以做起来也很简单。
namespace output {
using std::map;
using std::string;
void write(FILE* file, string const& str) {
// Write the length of the string, followed by a space
fprintf(file, "%lu ", str.size());
// Write the string itself
fwrite(str.data(), 1, str.size(), file);
}
template<class Key, class Value>
void write(FILE* file, map<Key, Value> const& m) {
// Write the length of the map, followed by a space
fprintf(file, "%lu ", m.size());
for(auto& entry : m) {
// Write the key
write(file, entry.first);
// Write the value
write(file, entry.second);
}
}
}
从文件中读取 map
这也很简单。例如,要读取一个字符串,我们读取长度,然后读取所有字符。
namespace input {
using std::map;
using std::string;
void read(FILE* file, size_t& length) {
int result = fscanf(file, "%lu ", &length);
if(result < 0) throw std::logic_error("Couldn't read from file");
}
void read(FILE* file, string& str) {
size_t length; // Read the length
read(file, length);
str.resize(length);
size_t n_read = fread(&str[0], 1, length, file); // Read the characters
if(n_read != length) { // Handle errors
throw std::logic_error("Unable to read entirety of string from file");
}
}
template<class Key, class Value>
void read(FILE* file, map<Key, Value>& text) {
size_t length; // Read the length of the map
read(file, length);
text.clear();
for(size_t i = 0; i < length; i++) {
Key key;
read(file, key); // Read the key
read(file, text[key]); // Read the value
}
}
}
使用这段代码
写 map :
void write_map(string file, map<string, map<string, string>> test_map) {
auto output_file = fopen(file.c_str(), "w");
output::write(output_file, test_map);
fclose(output_file);
}
阅读 map :
map<string, map<string, string>> read_map(string file) {
auto input_file = fopen(file.c_str(), "r");
map<string, map<string, string>> m;
input::read(file, m);
fclose(input_file);
return m;
}
测试这段代码
You can see a live demonstration here
这个主要功能会将测试 map 写入文件,然后将其读回不同的 map ,然后比较两者。
int main() {
using std::map;
using std::string;
map<string, map<string, string>> test_map {
{"Hello", {{"A", "B"}, {"C", "D"}}},
{"World", {{"Blarg", "glug glug glug"}, {"idek what to put here", "felt cute might delete later"}}}
};
{
auto output_file = fopen("example.txt", "w");
output::write(output_file, test_map);
fclose(output_file);
}
map<string, map<string, string>> map_from_file;
{
auto input_file = fopen("example.txt", "r");
try {
input::read(input_file, map_from_file);
} catch(std::logic_error& err) {
std::cerr << "Reading example.txt failed: " << err.what() << '\n';
}
fclose(input_file);
}
std::cout << std::boolalpha << "Maps equivilant? " << (test_map == map_from_file) << '\n';
for(auto pair : map_from_file) {
std::cout << '"' << pair.first << "\" -> {\n";
for(auto kv : pair.second) {
std::cout << " \"" << kv.first << "\" -> \"" << kv.second << '"' << "\n";
}
std::cout << "}\n";
}
}
关于python - 如何在 C++ 中高效地创建和编译大 map ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56875729/