Комментарии 40
Я так понимаю, читать файл обратно, задачи не стоит.
+9
Есть ещё одна open source библиотека для работы с json (JsonBox), очень удобная в использовании, осваивается минут за 5.
+1
А если в строке будет кавычка? Не нашел в коде экранирование.
+3
О! Вéлик!
+23
Это понятно, что лисапед. Надеюсь, что оригинальный. Такого наглого использования цикла for я нигде сам не встречал :).
0
Согласен. Да и main для неокрепших умов выглядит так, что хочется руки поотрывать посмотреть как и зачем такое сделано.
На фоне этой красоты
смотрится не очень.
На фоне этой красоты
//Внутри массива ключ игнорируется, даже если ошибочно задан
смотрится не очень.
+1
Рубанул комментарии. А за что руки оторвать, можно подробнее? Ну за (char *)&i, оно понятно, а еще?
0
Дело не в комментарии, а в том, что параметр не нужен.
Ну, за оригинальную запись. Вам-то оно понятно, а любой непосвященный сразу думает «WTF?» И только потом, если разберется «О, как красиво!» ;)
Ну, за оригинальную запись. Вам-то оно понятно, а любой непосвященный сразу думает «WTF?» И только потом, если разберется «О, как красиво!» ;)
0
Эх, если бы я умел делать #define FOO(...) с переменным числом аргументов, то можно было бы еще красивее забацать. В JSONе можно использовать null в качестве значения, так и напрашивается сделать его через VALUE(«Key»), а вот фиг. Но я еще работаю над этой проблемой ;).
Еще очень напрягает, что нельзя нормально перегрузить функции TJsonTagCloser::Write***. Используются-то его наследники, не в каждом же перегружать. Тоже думаю, как сделать красиво.
Еще очень напрягает, что нельзя нормально перегрузить функции TJsonTagCloser::Write***. Используются-то его наследники, не в каждом же перегружать. Тоже думаю, как сделать красиво.
0
Начиная с C99 и C++11макросы с переменнымм числом параметров делать можно Variadic macros
0
Но велосипед не плохой получился :)
+2
Согласен с предыдущими комментаторами. Есть вещи, самостоятельно писать которые следует только в исключительных случаях.
blog.newrelic.com/2014/07/08/7-things-never-code/
blog.newrelic.com/2014/07/08/7-things-never-code/
+8
Я с этим согласен. Но я непрофессиональный программист, поэтому такие задачи для меня скорее тренировка и даже что-то вроде хобби. У меня редко получается хороший код, но тут, похоже, исключение. Если честно, то сам офигел от чистоты и естественности скрипта описания формата данных, насколько хорошо в него вписываются конструкции С++. Собственно поэтому и рискнул показать общественности.
-1
Советую rapidjson. Из преимуществ — кроссплатформенный, быстрый, понимает различные кодировки, хорошо документирован и поддерживает или будет новые изменения в С++11. Велосипед, конечно, хорошо делать когда есть время или для учебы, но это не настолько интересно чтобы писать свой 101 парсер(писатель) Json/Xml формата.
+1
json всем хорош, но вот с датами там не все гладко в отличии от xml
-3
Очень интересно послушать что именно. Как по мне, текст и там, и там.
+1
json не предлагает определенного формата представления даты/времени, из-за чего могут возникнуть проблемы при его использовании между php и .net например. http://stackoverflow.com/questions/10286204/the-right-json-date-format
0
У xml существует такое понятие, как схема — которая подскажет, где текст — это просто текст, а где он вообще-то дата. Схема может быть строгой (значение такого-то атрибута — всегда дата) или нестрогой (дата в тексте выделяется тегом date), но она всегда есть. Более того, в xml парсинг даты ничем не отличается от, к примеру, парсинга числа.
json же изначально притворяется, что не требует никакой схемы данных. Еще он притворяется, что способен самостоятельно отличить строку от числа — это принципиально разные литералы, числа не надо парсить! Наконец, он притворяется (в случае javascript) одним большим составным литералом объекта, с которым можно работать сразу же, не пропуская его через слой обработки входных данных. Но стоит попытаться передать дату — и сразу же выясняется, что нам надо знать, где эта дата находится, как ее парсить — и желательно ее парсить не в коде логики программы — а сразу по получении.
Надо понимать, что это не является недостатком json. Просто если надо часто работать с датами — то json оказывается ничем не проще xml.
json же изначально притворяется, что не требует никакой схемы данных. Еще он притворяется, что способен самостоятельно отличить строку от числа — это принципиально разные литералы, числа не надо парсить! Наконец, он притворяется (в случае javascript) одним большим составным литералом объекта, с которым можно работать сразу же, не пропуская его через слой обработки входных данных. Но стоит попытаться передать дату — и сразу же выясняется, что нам надо знать, где эта дата находится, как ее парсить — и желательно ее парсить не в коде логики программы — а сразу по получении.
Надо понимать, что это не является недостатком json. Просто если надо часто работать с датами — то json оказывается ничем не проще xml.
+2
полностью с вами согласен
0
что значит числа не надо парсить? они передаются точно так же строкой в человекочитаемом виде, из этой строки все равно нужно парсить число
0
но она всегда естьЭто где она всегда есть? Сколько API сайтов не перелопатил, нигде не встречал. XML Schema существует так же, как и JSON Schema (документ IETF, между прочим). А вот то, что на практике его мало кто использует, это уже другой вопрос.
+3
Чому бы не осилить boost::property_tree?
#include <iostream>
#include <unordered_map>
#include <boost/property_tree/json_parser.hpp>
int main()
{
auto pt = boost::property_tree::ptree{};
pt.put("Comment", "My comment");
pt.put("Count", 10);
pt.put("DiskParam.DB", 10.0);
pt.put("DiskParam.DBAngle", 1.234);
pt.put("Range", true);
auto blades = std::unordered_map<std::string, int>{{"A", 1}, {"B", 2}, {"C", 2}};
auto bladesTree = boost::property_tree::ptree{};
for (const auto &kv : blades) {
auto blade = boost::property_tree::ptree{};
blade.add("Caption", kv.first);
blade.add("Value", kv.second);
bladesTree.push_back(std::make_pair("", blade));
}
pt.add_child("Blades", bladesTree);
auto slotsTree = boost::property_tree::ptree{};
for (auto i = 0; i < 3; i++) {
auto slot = boost::property_tree::ptree{std::to_string(i)};
slotsTree.push_back(std::make_pair("", slot));
}
pt.add_child("Slots", slotsTree);
auto buf = std::ostringstream{};
boost::property_tree::write_json(buf, pt);
std::cout << buf.str();
}
+2
Хмм…
Простой аналог на Haskell (inspired by realworldhaskell):
Кажется компактнее получилось :)
Простой аналог на Haskell (inspired by realworldhaskell):
import Data.Char
import Data.List (intercalate)
data JValue = JString String
| JNumber Double
| JBool Bool
| JNull
| JObject [(String, JValue)]
| JArray [JValue]
deriving Show
renderJValue :: JValue -> String
renderJValue (JString s) = show s
renderJValue (JNumber n) = show n
renderJValue (JBool True) = "true"
renderJValue (JBool False) = "false"
renderJValue JNull = "null"
renderJValue (JObject o) = "{" ++ pairs o ++ "}"
where pairs [] = ""
pairs ps = intercalate ", " (map renderPair ps)
renderPair (k, v) = show k ++ ": " ++ renderJValue v
renderJValue (JArray a) = "[" ++ values a ++ "]"
where values [] = ""
values vs = intercalate ", " (map renderJValue vs)
main = putStrLn $ renderJValue (JObject [
("Comment", JString "My comment"),
("Count", JNumber 10),
("DiskParam", JObject [
("DB", JNumber 10),
("DBAngle", JNumber 1.234)
]),
("Range", JBool True),
("Blades", JArray $ map (\ch ->
JObject [
("Caption", JString (ch:[])),
("Value", JNumber (fromIntegral (ord ch)))
]) ['A'..'C']),
("Slots", JArray [JNumber 0, JNumber 1, JNumber 2])
])
Кажется компактнее получилось :)
+2
Ищущие компактности используют Javascript (JSON.stringify) или Python (json.dumps). Инициализация сериализуемых объектов в этих языках совпадает по синтаксису с JSON.
А все велосипедисты навернутся на первой неэкранированной кавычке, бэкслеше, на переносах строк, на юникоде и много ещё на чём.
А все велосипедисты навернутся на первой неэкранированной кавычке, бэкслеше, на переносах строк, на юникоде и много ещё на чём.
+1
Ого! В такой размер исходника я не помещусь, даже если максимально выжать из него всю воду. Но за первенство по размеру исполняемого файла вполне поборюсь, предполагаю влезть в 4Кб.
Забавный язык, спасибо за комментарий.
Забавный язык, спасибо за комментарий.
0
Вспомнился мой наивный XML-парсер… Да, все мы иногда пишем велосипеды ;)
+1
Совет программисту на любом языке: погляди, нет ли в конце страницы http://json.org/ исходного кода для работы с JSON на твоём языке.
Если есть — то не пиши собственный код. (Если неймётся, то пиши — но не используй в деле до тех пор, пока он не станет во всём лучше имеющегося.)
Если есть — то не пиши собственный код. (Если неймётся, то пиши — но не используй в деле до тех пор, пока он не станет во всём лучше имеющегося.)
+8
Вы будете смеяться, но я пишу с использованием разработанной технологии еще один вЕлик. Библиотеку чтения JSON. Примерно так выглядит это самое чтение в программе:
OBJECT("")
{
VALUE("Comment", Header.Comment);
VALUE("Count", Header.Count);
OBJECT("DiskParam")
{
VALUE("DB", Header.DB);
VALUE("DBAngle", Header.DBAngle);
}
VALUE("Range", Header.Range);
//Чтение массива с неизвестным числом элементов
ARRAY_WHILE("Blades", BladeCount)
{
TBlade Blade;
OBJECT("")
{
VALUE("Caption", Blade.Caption);
VALUE("Value", Blade.BaseChar);
}
if(!ERROR)
{
NewBlades=realloc(Blades, BladeCount+1);
if(NewBlades)
{
Blades=NewBlades;
Blades[BladeCount]=Blade;
}
}
}
//Чтение массива с известным или ограниченным числом элементов
ARRAY_FOR("Slots", SlotsCount, MAX_ELEMENTS)
VALUE("", Slots[SlotsCount]);
//Обработка ситуаций, когда значение может быть неподходящего типа
double Temp;
VALUE("NCount", Temp)
Header.NCount=(int)(Temp+0.5);
}
Я просто уверен, такого синтаксиса вы еще нигде не видели :). Имеет смысл писать статью или снова заминусуете велосипедиста?0
Библиотеки хоть совместимы? Я думаю, в хабе «Ненормальное программирование» никто минусовать не будет.
0
Это же убого! Бросьте Вы это. Уверяю спустя некоторое время «Вы-в-будущем» очень не хорошо выскажется о «Вы-сейчас»!
-1
Зарегистрируйтесь на Хабре, чтобы оставить комментарий
Запись данных в формате JSON