Запись данных в формате JSON
В одной из моих программ понадобилась запись данных в формате JSON. Вкратце — XML-подобный формат, вполне подходит на замену Windows INI-файлам или тому же XML. Удобен тем, что поддерживает массивы и вложенность собственных структур, но при этом не замусоривает файл данных своими тегами до полной нечитабельности человеком. Вот пример файла данных:
{
"Comment":"My comment",
"Count":10,
"DiskParam":
{
"DB":10.000000,
"DBAngle":1.234000
},
"Range":true,
"Blades":
[
{
"Caption":"A",
"Value":65
},
{
"Caption":"B",
"Value":66
},
{
"Caption":"C",
"Value":67
}
],
"Slots":
[
0,1,2
]
}
Формат довольно простой, вполне можно работать с ним без всяких библиотек. Поэтому первоначально за запись отвечал примерно такой участок кода:
fprintf(pOut, "{\n");
fprintf(pOut, " \"Comment\":\"%s\"", Header->Comment);
fprintf(pOut, ",\n \"NumSt\":%d", Header->NumSt);
//Пропущено немного кода
fprintf(pOut, ",\n \"DBMax\":%lf", Header->DBMax);
fprintf(pOut, ",\n \"Range\":%s", Header->Range?"true":"false");
fprintf(pOut, ",\n \"Blades\":\n [");
for(int i=0; i<Header->Count; i++)
{
TElement &e=Element[i];
fprintf(pOut, i?",\n {":"\n {");
fprintf(pOut, "\"Caption\":\"%s\"", e.Caption);
fprintf(pOut, ",\"Value\":%lf", e.BaseChar);
fprintf(pOut, "}");
}
fprintf(pOut, "\n ]");
//Пропущено много кода
fprintf(pOut, "\n}");
Корявенько, хотя вполне работоспособно. Но программа активно дорабатывалась, формат данных менялся по 5 раз на дню и остро встала проблема отслеживания всех изменений. Несмотря на некоторое форматирование исходника было тяжело не забыть закрыть какой-нибудь тег или правильно напечатать нужное число пробелов для форматирования уже собственно файла данных. Даже в приведенном фрагменте перед публикацией обнаружилась ошибка, не ставилась запятая между элементами массива.
Решил я этот техпроцесс слегка механизировать и создать микробиблиотеку для работы с JSON.