Запись данных в формате 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.
Читать полностью »