当前,我有多个json文件和一个python代码,该代码读取json文件main.json之一,并基于json文件创建完整的c ++代码。在该c ++的main()中,我需要使用numberToString.json将数字输出转换为字符串。我找不到及时(<1分钟)成功编译C ++代码的方法
我在c ++文件中创建了一个嵌套映射“ std :: map
示例代码:
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 ,以 “新鲜”显示 ,使用numberToString.json。
我正在使用python 2.7
答案 0 :(得分:1)
您绝对不应该自动生成像这样对地图进行硬编码的C ++代码。有一些库可以将json文件直接读取到C ++中(例如,请参见rapid json),而应该使用这些库。该代码将编译得更快,并且读取20,000个文件所花费的时间应该在几毫秒的数量级(而不是需要花费超过5分钟的时间)。
如果要避免在C ++代码中添加对json解析器的依赖关系,建议将JSON文件转换为更简单的格式,以使C ++更易于阅读。
让我们看一个简单的地图:
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 length> <map key-value pairs>
。因此,例如,"Hello world"
将被写为11 Hello world
。对于上面的地图,对应的文件是
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,这意味着顶层地图具有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);
}
}
}
这也非常简单。例如,要读取一个字符串,我们先读取长度,然后读取所有字符。
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
}
}
}
要编写地图:
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<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
此主要功能会将测试图写入文件,然后将其读回不同的图,然后将两者进行比较。
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";
}
}