Overview¶
Base type¶
All exceptions inherit from class json::exception
(which in turn inherits from std::exception
). It is used as the base class for all exceptions thrown by the basic_json
class. This class can hence be used as «wildcard» to catch exceptions.
Switch off exceptions¶
Exceptions are used widely within the library. They can, however, be switched off with either using the compiler flag -fno-exceptions
or by defining the symbol JSON_NOEXCEPTION
. In this case, exceptions are replaced by abort()
calls. You can further control this behavior by defining JSON_THROW_USER
(overriding throw
), JSON_TRY_USER
(overriding try
), and JSON_CATCH_USER
(overriding catch
).
Note that JSON_THROW_USER
should leave the current scope (e.g., by throwing or aborting), as continuing after it may yield undefined behavior.
Example
The code below switches off exceptions and creates a log entry with a detailed error message in case of errors.
#include <iostream>
#define JSON_TRY_USER if(true)
#define JSON_CATCH_USER(exception) if(false)
#define JSON_THROW_USER(exception)
{std::clog << "Error in " << __FILE__ << ":" << __LINE__
<< " (function " << __FUNCTION__ << ") - "
<< (exception).what() << std::endl;
std::abort();}
#include <nlohmann/json.hpp>
Note the explanatory what()
string of exceptions is not available for MSVC if exceptions are disabled, see #2824.
See documentation of JSON_TRY_USER
, JSON_CATCH_USER
and JSON_THROW_USER
for more information.
Extended diagnostic messages¶
Exceptions in the library are thrown in the local context of the JSON value they are detected. This makes detailed diagnostics messages, and hence debugging, difficult.
Example
#include <iostream>
#include <nlohmann/json.hpp>
using json = nlohmann::json;
int main()
{
json j;
j["address"]["street"] = "Fake Street";
j["address"]["housenumber"] = "12";
try
{
int housenumber = j["address"]["housenumber"];
}
catch (json::exception& e)
{
std::cout << e.what() << 'n';
}
}
Output:
[json.exception.type_error.302] type must be number, but is string
This exception can be hard to debug if storing the value "12"
and accessing it is further apart.
To create better diagnostics messages, each JSON value needs a pointer to its parent value such that a global context (i.e., a path from the root value to the value that lead to the exception) can be created. That global context is provided as JSON Pointer.
As this global context comes at the price of storing one additional pointer per JSON value and runtime overhead to maintain the parent relation, extended diagnostics are disabled by default. They can, however, be enabled by defining the preprocessor symbol JSON_DIAGNOSTICS
to 1
before including json.hpp
.
Example
#include <iostream>
# define JSON_DIAGNOSTICS 1
#include <nlohmann/json.hpp>
using json = nlohmann::json;
int main()
{
json j;
j["address"]["street"] = "Fake Street";
j["address"]["housenumber"] = "12";
try
{
int housenumber = j["address"]["housenumber"];
}
catch (json::exception& e)
{
std::cout << e.what() << 'n';
}
}
Output:
[json.exception.type_error.302] (/address/housenumber) type must be number, but is string
Now the exception message contains a JSON Pointer /address/housenumber
that indicates which value has the wrong type.
See documentation of JSON_DIAGNOSTICS
for more information.
Parse errors¶
This exception is thrown by the library when a parse error occurs. Parse errors can occur during the deserialization of JSON text, CBOR, MessagePack, as well as when using JSON Patch.
Exceptions have ids 1xx.
Byte index
Member byte
holds the byte index of the last read character in the input file.
For an input with n bytes, 1 is the index of the first character and n+1 is the index of the terminating null byte or the end of file. This also holds true when reading a byte vector (CBOR or MessagePack).
Example
The following code shows how a parse_error
exception can be caught.
#include <iostream>
#include <nlohmann/json.hpp>
using json = nlohmann::json;
int main()
{
try
{
// parsing input with a syntax error
json::parse("[1,2,3,]");
}
catch (json::parse_error& e)
{
// output exception information
std::cout << "message: " << e.what() << 'n'
<< "exception id: " << e.id << 'n'
<< "byte position of error: " << e.byte << std::endl;
}
}
Output:
message: [json.exception.parse_error.101] parse error at line 1, column 8: syntax error while parsing value - unexpected ']'; expected '[', '{', or a literal
exception id: 101
byte position of error: 8
json.exception.parse_error.101¶
This error indicates a syntax error while deserializing a JSON text. The error message describes that an unexpected token (character) was encountered, and the member byte
indicates the error position.
Example message
Input ended prematurely:
[json.exception.parse_error.101] parse error at 2: unexpected end of input; expected string literal
No input:
[json.exception.parse_error.101] parse error at line 1, column 1: syntax error while parsing value - unexpected end of input; expected '[', '{', or a literal
Control character was not escaped:
[json.exception.parse_error.101] parse error at line 1, column 2: syntax error while parsing value - invalid string: control character U+0009 (HT) must be escaped to u0009 or \; last read: '"<U+0009>'"
String was not closed:
[json.exception.parse_error.101] parse error at line 1, column 2: syntax error while parsing value - invalid string: missing closing quote; last read: '"'
Invalid number format:
[json.exception.parse_error.101] parse error at line 1, column 3: syntax error while parsing value - invalid number; expected '+', '-', or digit after exponent; last read: '1E'
u
was not be followed by four hex digits:
[json.exception.parse_error.101] parse error at line 1, column 6: syntax error while parsing value - invalid string: 'u' must be followed by 4 hex digits; last read: '"u01"'
Invalid UTF-8 surrogate pair:
[json.exception.parse_error.101] parse error at line 1, column 13: syntax error while parsing value - invalid string: surrogate U+DC00..U+DFFF must follow U+D800..U+DBFF; last read: '"uD7FFuDC00'"
Invalid UTF-8 byte:
[json.exception.parse_error.101] parse error at line 3, column 24: syntax error while parsing value - invalid string: ill-formed UTF-8 byte; last read: '"vous 352t'
Tip
- Make sure the input is correctly read. Try to write the input to standard output to check if, for instance, the input file was successfully opened.
- Paste the input to a JSON validator like http://jsonlint.com or a tool like jq.
json.exception.parse_error.102¶
JSON uses the uxxxx
format to describe Unicode characters. Code points above 0xFFFF are split into two uxxxx
entries («surrogate pairs»). This error indicates that the surrogate pair is incomplete or contains an invalid code point.
Example message
parse error at 14: missing or wrong low surrogate
Note
This exception is not used any more. Instead json.exception.parse_error.101 with a more detailed description is used.
json.exception.parse_error.103¶
Unicode supports code points up to 0x10FFFF. Code points above 0x10FFFF are invalid.
Example message
parse error: code points above 0x10FFFF are invalid
Note
This exception is not used any more. Instead json.exception.parse_error.101 with a more detailed description is used.
json.exception.parse_error.104¶
RFC 6902 requires a JSON Patch document to be a JSON document that represents an array of objects.
Example message
[json.exception.parse_error.104] parse error: JSON patch must be an array of objects
json.exception.parse_error.105¶
An operation of a JSON Patch document must contain exactly one «op» member, whose value indicates the operation to perform. Its value must be one of «add», «remove», «replace», «move», «copy», or «test»; other values are errors.
Example message
[json.exception.parse_error.105] parse error: operation 'add' must have member 'value'
[json.exception.parse_error.105] parse error: operation 'copy' must have string member 'from'
[json.exception.parse_error.105] parse error: operation value 'foo' is invalid
json.exception.parse_error.106¶
An array index in a JSON Pointer (RFC 6901) may be 0
or any number without a leading 0
.
Example message
[json.exception.parse_error.106] parse error: array index '01' must not begin with '0'
json.exception.parse_error.107¶
A JSON Pointer must be a Unicode string containing a sequence of zero or more reference tokens, each prefixed by a /
character.
Example message
[json.exception.parse_error.107] parse error at byte 1: JSON pointer must be empty or begin with '/' - was: 'foo'
json.exception.parse_error.108¶
In a JSON Pointer, only ~0
and ~1
are valid escape sequences.
Example message
[json.exception.parse_error.108] parse error: escape character '~' must be followed with '0' or '1'
json.exception.parse_error.109¶
A JSON Pointer array index must be a number.
Example messages
[json.exception.parse_error.109] parse error: array index 'one' is not a number
[json.exception.parse_error.109] parse error: array index '+1' is not a number
json.exception.parse_error.110¶
When parsing CBOR or MessagePack, the byte vector ends before the complete value has been read.
Example message
[json.exception.parse_error.110] parse error at byte 5: syntax error while parsing CBOR string: unexpected end of input
[json.exception.parse_error.110] parse error at byte 2: syntax error while parsing UBJSON value: expected end of input; last byte: 0x5A
json.exception.parse_error.112¶
An unexpected byte was read in a binary format or length information is invalid (BSON).
Example messages
[json.exception.parse_error.112] parse error at byte 1: syntax error while parsing CBOR value: invalid byte: 0x1C
[json.exception.parse_error.112] parse error at byte 1: syntax error while parsing MessagePack value: invalid byte: 0xC1
[json.exception.parse_error.112] parse error at byte 4: syntax error while parsing BJData size: expected '#' after type information; last byte: 0x02
[json.exception.parse_error.112] parse error at byte 4: syntax error while parsing UBJSON size: expected '#' after type information; last byte: 0x02
[json.exception.parse_error.112] parse error at byte 10: syntax error while parsing BSON string: string length must be at least 1, is -2147483648
[json.exception.parse_error.112] parse error at byte 15: syntax error while parsing BSON binary: byte array length cannot be negative, is -1
json.exception.parse_error.113¶
While parsing a map key, a value that is not a string has been read.
Example messages
[json.exception.parse_error.113] parse error at byte 2: syntax error while parsing CBOR string: expected length specification (0x60-0x7B) or indefinite string type (0x7F); last byte: 0xFF
[json.exception.parse_error.113] parse error at byte 2: syntax error while parsing MessagePack string: expected length specification (0xA0-0xBF, 0xD9-0xDB); last byte: 0xFF
[json.exception.parse_error.113] parse error at byte 2: syntax error while parsing UBJSON char: byte after 'C' must be in range 0x00..0x7F; last byte: 0x82
json.exception.parse_error.114¶
The parsing of the corresponding BSON record type is not implemented (yet).
Example message
[json.exception.parse_error.114] parse error at byte 5: Unsupported BSON record type 0xFF
json.exception.parse_error.115¶
A UBJSON high-precision number could not be parsed.
Example message
[json.exception.parse_error.115] parse error at byte 5: syntax error while parsing UBJSON high-precision number: invalid number text: 1A
Iterator errors¶
This exception is thrown if iterators passed to a library function do not match the expected semantics.
Exceptions have ids 2xx.
Example
The following code shows how an invalid_iterator
exception can be caught.
#include <iostream>
#include <nlohmann/json.hpp>
using json = nlohmann::json;
int main()
{
try
{
// calling iterator::key() on non-object iterator
json j = "string";
json::iterator it = j.begin();
auto k = it.key();
}
catch (json::invalid_iterator& e)
{
// output exception information
std::cout << "message: " << e.what() << 'n'
<< "exception id: " << e.id << std::endl;
}
}
Output:
message: [json.exception.invalid_iterator.207] cannot use key() for non-object iterators
exception id: 207
json.exception.invalid_iterator.201¶
The iterators passed to constructor basic_json(InputIT first, InputIT last)
are not compatible, meaning they do not belong to the same container. Therefore, the range (first
, last
) is invalid.
Example message
[json.exception.invalid_iterator.201] iterators are not compatible
json.exception.invalid_iterator.202¶
In the erase or insert function, the passed iterator pos
does not belong to the JSON value for which the function was called. It hence does not define a valid position for the deletion/insertion.
Example messages
[json.exception.invalid_iterator.202] iterator does not fit current value
[json.exception.invalid_iterator.202] iterators first and last must point to objects
json.exception.invalid_iterator.203¶
Either iterator passed to function erase(IteratorType first, IteratorType last
) does not belong to the JSON value from which values shall be erased. It hence does not define a valid range to delete values from.
Example message
[json.exception.invalid_iterator.203] iterators do not fit current value
json.exception.invalid_iterator.204¶
When an iterator range for a primitive type (number, boolean, or string) is passed to a constructor or an erase function, this range has to be exactly (begin(),
end()),
because this is the only way the single stored value is expressed. All other ranges are invalid.
Example message
[json.exception.invalid_iterator.204] iterators out of range
json.exception.invalid_iterator.205¶
When an iterator for a primitive type (number, boolean, or string) is passed to an erase function, the iterator has to be the begin()
iterator, because it is the only way to address the stored value. All other iterators are invalid.
Example message
[json.exception.invalid_iterator.205] iterator out of range
json.exception.invalid_iterator.206¶
The iterators passed to constructor basic_json(InputIT first, InputIT last)
belong to a JSON null value and hence to not define a valid range.
Example message
[json.exception.invalid_iterator.206] cannot construct with iterators from null
json.exception.invalid_iterator.207¶
The key()
member function can only be used on iterators belonging to a JSON object, because other types do not have a concept of a key.
Example message
[json.exception.invalid_iterator.207] cannot use key() for non-object iterators
json.exception.invalid_iterator.208¶
The operator[]
to specify a concrete offset cannot be used on iterators belonging to a JSON object, because JSON objects are unordered.
Example message
[json.exception.invalid_iterator.208] cannot use operator[] for object iterators
json.exception.invalid_iterator.209¶
The offset operators (+
, -
, +=
, -=
) cannot be used on iterators belonging to a JSON object, because JSON objects are unordered.
Example message
[json.exception.invalid_iterator.209] cannot use offsets with object iterators
json.exception.invalid_iterator.210¶
The iterator range passed to the insert function are not compatible, meaning they do not belong to the same container. Therefore, the range (first
, last
) is invalid.
Example message
[json.exception.invalid_iterator.210] iterators do not fit
json.exception.invalid_iterator.211¶
The iterator range passed to the insert function must not be a subrange of the container to insert to.
Example message
[json.exception.invalid_iterator.211] passed iterators may not belong to container
json.exception.invalid_iterator.212¶
When two iterators are compared, they must belong to the same container.
Example message
[json.exception.invalid_iterator.212] cannot compare iterators of different containers
json.exception.invalid_iterator.213¶
The order of object iterators cannot be compared, because JSON objects are unordered.
Example message
[json.exception.invalid_iterator.213] cannot compare order of object iterators
json.exception.invalid_iterator.214¶
Cannot get value for iterator: Either the iterator belongs to a null value or it is an iterator to a primitive type (number, boolean, or string), but the iterator is different to begin()
.
Example message
[json.exception.invalid_iterator.214] cannot get value
Type errors¶
This exception is thrown in case of a type error; that is, a library function is executed on a JSON value whose type does not match the expected semantics.
Exceptions have ids 3xx.
Example
The following code shows how a type_error
exception can be caught.
#include <iostream>
#include <nlohmann/json.hpp>
using json = nlohmann::json;
int main()
{
try
{
// calling push_back() on a string value
json j = "string";
j.push_back("another string");
}
catch (json::type_error& e)
{
// output exception information
std::cout << "message: " << e.what() << 'n'
<< "exception id: " << e.id << std::endl;
}
}
Output:
message: [json.exception.type_error.308] cannot use push_back() with string
exception id: 308
json.exception.type_error.301¶
To create an object from an initializer list, the initializer list must consist only of a list of pairs whose first element is a string. When this constraint is violated, an array is created instead.
Example message
[json.exception.type_error.301] cannot create object from initializer list
json.exception.type_error.302¶
During implicit or explicit value conversion, the JSON type must be compatible to the target type. For instance, a JSON string can only be converted into string types, but not into numbers or boolean types.
Example messages
[json.exception.type_error.302] type must be object, but is null
[json.exception.type_error.302] type must be string, but is object
json.exception.type_error.303¶
To retrieve a reference to a value stored in a basic_json
object with get_ref
, the type of the reference must match the value type. For instance, for a JSON array, the ReferenceType
must be array_t &
.
Example messages
[json.exception.type_error.303] incompatible ReferenceType for get_ref, actual type is object
[json.exception.type_error.303] incompatible ReferenceType for get_ref, actual type is number"
json.exception.type_error.304¶
The at()
member functions can only be executed for certain JSON types.
Example messages
[json.exception.type_error.304] cannot use at() with string
[json.exception.type_error.304] cannot use at() with number
json.exception.type_error.305¶
The operator[]
member functions can only be executed for certain JSON types.
Example messages
[json.exception.type_error.305] cannot use operator[] with a string argument with array
[json.exception.type_error.305] cannot use operator[] with a numeric argument with object
json.exception.type_error.306¶
The value()
member functions can only be executed for certain JSON types.
Example message
[json.exception.type_error.306] cannot use value() with number
json.exception.type_error.307¶
The erase()
member functions can only be executed for certain JSON types.
Example message
[json.exception.type_error.307] cannot use erase() with string
json.exception.type_error.308¶
The push_back()
and operator+=
member functions can only be executed for certain JSON types.
Example message
[json.exception.type_error.308] cannot use push_back() with string
json.exception.type_error.309¶
The insert()
member functions can only be executed for certain JSON types.
Example messages
[json.exception.type_error.309] cannot use insert() with array
[json.exception.type_error.309] cannot use insert() with number
json.exception.type_error.310¶
The swap()
member functions can only be executed for certain JSON types.
Example message
[json.exception.type_error.310] cannot use swap() with number
json.exception.type_error.311¶
The emplace()
and emplace_back()
member functions can only be executed for certain JSON types.
Example messages
[json.exception.type_error.311] cannot use emplace() with number
[json.exception.type_error.311] cannot use emplace_back() with number
json.exception.type_error.312¶
The update()
member functions can only be executed for certain JSON types.
Example message
[json.exception.type_error.312] cannot use update() with array
json.exception.type_error.313¶
The unflatten
function converts an object whose keys are JSON Pointers back into an arbitrary nested JSON value. The JSON Pointers must not overlap, because then the resulting value would not be well-defined.
Example message
[json.exception.type_error.313] invalid value to unflatten
json.exception.type_error.314¶
The unflatten
function only works for an object whose keys are JSON Pointers.
Example message
Calling unflatten()
on an array [1,2,3]
:
[json.exception.type_error.314] only objects can be unflattened
json.exception.type_error.315¶
The unflatten()
function only works for an object whose keys are JSON Pointers and whose values are primitive.
Example message
Calling unflatten()
on an object {"/1", [1,2,3]}
:
[json.exception.type_error.315] values in object must be primitive
json.exception.type_error.316¶
The dump()
function only works with UTF-8 encoded strings; that is, if you assign a std::string
to a JSON value, make sure it is UTF-8 encoded.
Example message
Calling dump()
on a JSON value containing an ISO 8859-1 encoded string:
[json.exception.type_error.316] invalid UTF-8 byte at index 15: 0x6F
Tip
- Store the source file with UTF-8 encoding.
- Pass an error handler as last parameter to the
dump()
function to avoid this exception:json::error_handler_t::replace
will replace invalid bytes sequences withU+FFFD
json::error_handler_t::ignore
will silently ignore invalid byte sequences
json.exception.type_error.317¶
The dynamic type of the object cannot be represented in the requested serialization format (e.g. a raw true
or null
JSON object cannot be serialized to BSON)
Example messages
Serializing null
to BSON:
[json.exception.type_error.317] to serialize to BSON, top-level type must be object, but is null
Serializing [1,2,3]
to BSON:
[json.exception.type_error.317] to serialize to BSON, top-level type must be object, but is array
Tip
Encapsulate the JSON value in an object. That is, instead of serializing true
, serialize {"value": true}
Out of range¶
This exception is thrown in case a library function is called on an input parameter that exceeds the expected range, for instance in case of array indices or nonexisting object keys.
Exceptions have ids 4xx.
Example
The following code shows how an out_of_range
exception can be caught.
#include <iostream>
#include <nlohmann/json.hpp>
using json = nlohmann::json;
int main()
{
try
{
// calling at() for an invalid index
json j = {1, 2, 3, 4};
j.at(4) = 10;
}
catch (json::out_of_range& e)
{
// output exception information
std::cout << "message: " << e.what() << 'n'
<< "exception id: " << e.id << std::endl;
}
}
Output:
message: [json.exception.out_of_range.401] array index 4 is out of range
exception id: 401
json.exception.out_of_range.401¶
The provided array index i
is larger than size-1
.
Example message
array index 3 is out of range
json.exception.out_of_range.402¶
The special array index -
in a JSON Pointer never describes a valid element of the array, but the index past the end. That is, it can only be used to add elements at this position, but not to read it.
Example message
array index '-' (3) is out of range
json.exception.out_of_range.403¶
The provided key was not found in the JSON object.
json.exception.out_of_range.404¶
A reference token in a JSON Pointer could not be resolved.
Example message
unresolved reference token 'foo'
json.exception.out_of_range.405¶
The JSON Patch operations ‘remove’ and ‘add’ can not be applied to the root element of the JSON value.
Example message
JSON pointer has no parent
json.exception.out_of_range.406¶
A parsed number could not be stored as without changing it to NaN or INF.
Example message
number overflow parsing '10E1000'
json.exception.out_of_range.407¶
UBJSON and BSON only support integer numbers up to 9223372036854775807.
Example message
number overflow serializing '9223372036854775808'
Note
Since version 3.9.0, integer numbers beyond int64 are serialized as high-precision UBJSON numbers, and this exception does not further occur.
json.exception.out_of_range.408¶
The size (following #
) of an UBJSON array or object exceeds the maximal capacity.
Example message
excessive array size: 8658170730974374167
json.exception.out_of_range.409¶
Key identifiers to be serialized to BSON cannot contain code point U+0000, since the key is stored as zero-terminated c-string.
Example message
BSON key cannot contain code point U+0000 (at byte 2)
Further exceptions¶
This exception is thrown in case of errors that cannot be classified with the other exception types.
Exceptions have ids 5xx.
Example
The following code shows how an other_error
exception can be caught.
#include <iostream>
#include <nlohmann/json.hpp>
using json = nlohmann::json;
using namespace nlohmann::literals;
int main()
{
try
{
// executing a failing JSON Patch operation
json value = R"({
"best_biscuit": {
"name": "Oreo"
}
})"_json;
json patch = R"([{
"op": "test",
"path": "/best_biscuit/name",
"value": "Choco Leibniz"
}])"_json;
value.patch(patch);
}
catch (json::other_error& e)
{
// output exception information
std::cout << "message: " << e.what() << 'n'
<< "exception id: " << e.id << std::endl;
}
}
Output:
message: [json.exception.other_error.501] unsuccessful: {"op":"test","path":"/best_biscuit/name","value":"Choco Leibniz"}
exception id: 501
json.exception.other_error.501¶
A JSON Patch operation ‘test’ failed. The unsuccessful operation is also printed.
Example message
Executing {"op":"test", "path":"/baz", "value":"bar"}
on {"baz": "qux"}
:
[json.exception.other_error.501] unsuccessful: {"op":"test","path":"/baz","value":"bar"}
Last update: December 19, 2022
Hey, I have a JSON file with a configuration stored, which is just a dump of an object I have previously made with nlohmann::json. The content look like this
{"base_out_path":"/home/tools/minerva_out/.basis/","base_register_path":"/home/tools/minerva_out/.basis_registres/","max_registry_size":1073741824,"out_path":"/home/tools/minerva_out","register_path":"/home/tools/minerva_out/.identifiers"}
and pretty
{ "base_out_path":"/home/tools/minerva_out/.basis/", "base_register_path":"/home/tools/minerva_out/.basis_registres/", "max_registry_size":1073741824, "out_path":"/home/tools/minerva_out", "register_path":"/home/tools/minerva_out/.identifiers" }``` However, when I try to parse the data, I get this error: ```bash terminate called after throwing an instance of 'nlohmann::detail::parse_error' what(): [json.exception.parse_error.101] parse error at line 1, column 1: syntax error while parsing value - unexpected end of input; expected '[', '{', or a literal Aborted (core dumped)
This is how I read the file
inline nlohmann::json json_reader(const std::string& file_path) { nlohmann::json json_data; std::ifstream input(file_path); if(input.fail()) { throw std::runtime_error("Unable to open file " + file_path); } input >> json_data; return json_data; }
This is how I write the file
inline void json_writer(std::string path, nlohmann::json data) { std::ofstream json_out(path); json_out << data; json_out.close(); }
And this is the code where it fails:
int main(void) { ... nlohmann::json minerva_config = tartarus::readers::json_reader((homedir() + "/.minerva" + "/config.json")); minerva::minerva storage(minerva_config); ... } minerva::minerva(const nlohmann::json& config) { m_base_out_path = config["base_out_path"].get<std::string>(); m_base_registry_path = config["base_register_path"].get<std::string>(); m_out_path = config["out_path"].get<std::string>(); m_registry_path = config["register_path"].get<std::string>(); size_t registry_size = config["max_registry_size"].get<size_t>(); m_registry = model::registry(m_registry_path, m_base_registry_path, registry_size); ... }
I have not had problems with the read and write method before, so any idea as to why it fails?
I use clang 7 as my compiler
Содержание
- nlohmann::basic_json::parse¶
- Template parameters¶
- Parameters¶
- Return value¶
- Exception safety¶
- Exceptions¶
- Complexity¶
- Notes¶
- Examples¶
- See also¶
- Version history¶
- Exceptions¶
- Overview¶
- Base type¶
- Switch off exceptions¶
- Extended diagnostic messages¶
- Parse errors¶
- json.exception.parse_error.101¶
- json.exception.parse_error.102¶
- json.exception.parse_error.103¶
- json.exception.parse_error.104¶
- json.exception.parse_error.105¶
- json.exception.parse_error.106¶
- json.exception.parse_error.107¶
- json.exception.parse_error.108¶
- json.exception.parse_error.109¶
- json.exception.parse_error.110¶
- json.exception.parse_error.112¶
- Frequently Asked Questions (FAQ)¶
- Known bugs¶
- Brace initialization yields arrays¶
- Limitations¶
- Relaxed parsing¶
- Parse errors reading non-ASCII characters¶
- Wide string handling¶
- Failing to Parse Valid JSON #2209
- Comments
- What is the issue you have?
- What is the expected behavior?
- And what is the actual behavior instead?
- Which compiler and operating system are you using?
- Which version of the library did you use?
- If you experience a compilation error: can you compile and run the unit tests?
- nlohmann::basic_json¶
- Template parameters¶
- Specializations¶
- Iterator invalidation¶
- Requirements¶
- Basic¶
- Layout¶
- Library-wide¶
- Container¶
- Member types¶
- Exceptions¶
- Container types¶
- JSON value data types¶
- Parser callback¶
- Member functions¶
- Object inspection¶
- Value access¶
- Element access¶
nlohmann::basic_json::parse¶
Deserialize from a pair of character iterators
The value_type of the iterator must be an integral type with size of 1, 2 or 4 bytes, which will be interpreted respectively as UTF-8, UTF-16 and UTF-32.
Template parameters¶
A compatible input, for instance:
- an std::istream object
- a FILE pointer (must not be null)
- a C-style array of characters
- a pointer to a null-terminated string of single byte characters
- a std::string
- an object obj for which begin(obj) and end(obj) produces a valid pair of iterators.
IteratorType
a compatible iterator type, for instance.
- a pair of std::string::iterator or std::vector ::iterator
- a pair of pointers such as ptr and ptr + len
Parameters¶
Return value¶
Deserialized JSON value; in case of a parse error and allow_exceptions set to false , the return value will be value_t::discarded . The latter can be checked with is_discarded .
Exception safety¶
Strong guarantee: if an exception is thrown, there are no changes in the JSON value.
Exceptions¶
- Throws parse_error.101 in case of an unexpected token.
- Throws parse_error.102 if to_unicode fails or surrogate error.
- Throws parse_error.103 if to_unicode fails.
Complexity¶
Linear in the length of the input. The parser is a predictive LL(1) parser. The complexity can be higher if the parser callback function cb or reading from (1) the input i or (2) the iterator range [ first , last ] has a super-linear complexity.
Notes¶
(1) A UTF-8 byte order mark is silently ignored.
The precondition that a passed FILE pointer must not be null is enforced with a runtime assertion.
Examples¶
The example below demonstrates the parse() function reading from an array.
The example below demonstrates the parse() function with and without callback function.
The example below demonstrates the parse() function with and without callback function.
The example below demonstrates the parse() function reading from a contiguous container.
The example below demonstrates the parse() function reading from a string that is not null-terminated.
The example below demonstrates the parse() function reading from an iterator pair.
The example below demonstrates the effect of the allow_exceptions parameter in the ´parse()` function.
See also¶
- accept — check if the input is valid JSON
- operator>> — deserialize from stream
Version history¶
- Added in version 1.0.0.
- Overload for contiguous containers (1) added in version 2.0.3.
- Ignoring comments via ignore_comments added in version 3.9.0.
Overload (2) replaces calls to parse with a pair of iterators as their first parameter which has been deprecated in version 3.8.0. This overload will be removed in version 4.0.0. Please replace all calls like parse (< ptr , ptr + len >, . ); with parse ( ptr , ptr + len , . ); .
You should be warned by your compiler with a -Wdeprecated-declarations warning if you are using a deprecated function.
Источник
Exceptions¶
Overview¶
Base type¶
All exceptions inherit from class json::exception (which in turn inherits from std::exception ). It is used as the base class for all exceptions thrown by the basic_json class. This class can hence be used as «wildcard» to catch exceptions.
Switch off exceptions¶
Exceptions are used widely within the library. They can, however, be switched off with either using the compiler flag -fno-exceptions or by defining the symbol JSON_NOEXCEPTION . In this case, exceptions are replaced by abort() calls. You can further control this behavior by defining JSON_THROW_USER (overriding throw ), JSON_TRY_USER (overriding try ), and JSON_CATCH_USER (overriding catch ).
Note that JSON_THROW_USER should leave the current scope (e.g., by throwing or aborting), as continuing after it may yield undefined behavior.
The code below switches off exceptions and creates a log entry with a detailed error message in case of errors.
Note the explanatory what() string of exceptions is not available for MSVC if exceptions are disabled, see #2824.
Extended diagnostic messages¶
Exceptions in the library are thrown in the local context of the JSON value they are detected. This makes detailed diagnostics messages, and hence debugging, difficult.
This exception can be hard to debug if storing the value «12» and accessing it is further apart.
To create better diagnostics messages, each JSON value needs a pointer to its parent value such that a global context (i.e., a path from the root value to the value that lead to the exception) can be created. That global context is provided as JSON Pointer.
As this global context comes at the price of storing one additional pointer per JSON value and runtime overhead to maintain the parent relation, extended diagnostics are disabled by default. They can, however, be enabled by defining the preprocessor symbol JSON_DIAGNOSTICS to 1 before including json.hpp .
Now the exception message contains a JSON Pointer /address/housenumber that indicates which value has the wrong type.
Parse errors¶
This exception is thrown by the library when a parse error occurs. Parse errors can occur during the deserialization of JSON text, CBOR, MessagePack, as well as when using JSON Patch.
Exceptions have ids 1xx.
Member byte holds the byte index of the last read character in the input file.
For an input with n bytes, 1 is the index of the first character and n+1 is the index of the terminating null byte or the end of file. This also holds true when reading a byte vector (CBOR or MessagePack).
The following code shows how a parse_error exception can be caught.
json.exception.parse_error.101¶
This error indicates a syntax error while deserializing a JSON text. The error message describes that an unexpected token (character) was encountered, and the member byte indicates the error position.
Input ended prematurely:
Control character was not escaped:
String was not closed:
Invalid number format:
u was not be followed by four hex digits:
Invalid UTF-8 surrogate pair:
Invalid UTF-8 byte:
- Make sure the input is correctly read. Try to write the input to standard output to check if, for instance, the input file was successfully opened.
- Paste the input to a JSON validator like http://jsonlint.com or a tool like jq.
json.exception.parse_error.102¶
JSON uses the uxxxx format to describe Unicode characters. Code points above 0xFFFF are split into two uxxxx entries («surrogate pairs»). This error indicates that the surrogate pair is incomplete or contains an invalid code point.
This exception is not used any more. Instead json.exception.parse_error.101 with a more detailed description is used.
json.exception.parse_error.103¶
Unicode supports code points up to 0x10FFFF. Code points above 0x10FFFF are invalid.
This exception is not used any more. Instead json.exception.parse_error.101 with a more detailed description is used.
json.exception.parse_error.104¶
RFC 6902 requires a JSON Patch document to be a JSON document that represents an array of objects.
json.exception.parse_error.105¶
An operation of a JSON Patch document must contain exactly one «op» member, whose value indicates the operation to perform. Its value must be one of «add», «remove», «replace», «move», «copy», or «test»; other values are errors.
json.exception.parse_error.106¶
An array index in a JSON Pointer (RFC 6901) may be 0 or any number without a leading 0 .
json.exception.parse_error.107¶
A JSON Pointer must be a Unicode string containing a sequence of zero or more reference tokens, each prefixed by a / character.
json.exception.parse_error.108¶
In a JSON Pointer, only
1 are valid escape sequences.
json.exception.parse_error.109¶
A JSON Pointer array index must be a number.
json.exception.parse_error.110¶
When parsing CBOR or MessagePack, the byte vector ends before the complete value has been read.
json.exception.parse_error.112¶
An unexpected byte was read in a binary format or length information is invalid (BSON).
Источник
Frequently Asked Questions (FAQ)¶
Known bugs¶
Brace initialization yields arrays¶
yield different results ( [ true ] vs. true )?
This is a known issue, and — even worse — the behavior differs between GCC and Clang. The «culprit» for this is the library’s constructor overloads for initializer lists to allow syntax like
To avoid any confusion and ensure portable code, do not use brace initialization with the types basic_json , json , or ordered_json unless you want to create an object or array as shown in the examples above.
Limitations¶
Relaxed parsing¶
Can you add an option to ignore trailing commas?
This library does not support any feature which would jeopardize interoperability.
Parse errors reading non-ASCII characters¶
- Why is the parser complaining about a Chinese character?
- Does the library support Unicode?
- I get an exception [json.exception.parse_error.101] parse error at line 1, column 53: syntax error while parsing value — invalid string: ill-formed UTF-8 byte; last read: ‘»Testé$’)»
The library supports Unicode input as follows:
- Only UTF-8 encoded input is supported which is the default encoding for JSON according to RFC 8259.
- std::u16string and std::u32string can be parsed, assuming UTF-16 and UTF-32 encoding, respectively. These encodings are not supported when reading from files or other input containers.
- Other encodings such as Latin-1 or ISO 8859-1 are not supported and will yield parse or serialization errors.
- Unicode noncharacters will not be replaced by the library.
- Invalid surrogates (e.g., incomplete pairs such as uDEAD ) will yield parse errors.
- The strings stored in the library are UTF-8 encoded. When using the default string type ( std::string ), note that its length/size functions return the number of stored bytes rather than the number of characters or glyphs.
- When you store strings with different encodings in the library, calling dump() may throw an exception unless json::error_handler_t::replace or json::error_handler_t::ignore are used as error handlers.
In most cases, the parser is right to complain, because the input is not UTF-8 encoded. This is especially true for Microsoft Windows where Latin-1 or ISO 8859-1 is often the standard encoding.
Wide string handling¶
Why are wide strings (e.g., std::wstring ) dumped as arrays of numbers?
As described above, the library assumes UTF-8 as encoding. To store a wide string, you need to change the encoding.
Источник
Failing to Parse Valid JSON #2209
The library fails to parse seemingly-valid JSON
What is the issue you have?
This code snippet:
What is the expected behavior?
And what is the actual behavior instead?
A crash, seemingly when parsing the integers — it works when the integers are quoted.
Which compiler and operating system are you using?
Which version of the library did you use?
- latest release version 3.7.3
- other release — please state the version: ___
- the develop branch
If you experience a compilation error: can you compile and run the unit tests?
- yes
- no — please copy/paste the error message below
The text was updated successfully, but these errors were encountered:
I cannot reproduce the issue with the same compiler.
Full code for reference (using develop branch 29ad217):
Can you please double check your code?
I ran that exact code and got the same error. very strange! Let me try with that specific branch.
Can you try to execute the unit tests?
My «develop» was old. Works as expected with latest version. Thank you 🙂
Thanks for checking back!
I ran that exact code and got the same error. very strange! Let me try with that specific branch.
I get the same error on version 3.7.3 .
The error occurs occasionally, when I call a lot of json::parse func.
- macOS 10.14.6
The library will accept any valid JSON as long as it’s UTF-8 encoded. Can you copy the exact input and the code you use to parse it?
Sorry, I can’t provide the specific data, because I chunked a large file and called JSON:: parse to serialize it. I found this error in the log file, and I found that the error is not deterministic, even if the same input data. I will continue to test it with other third-party JSON libraries, and I will reply in time whether there is an error in my program itself or the cause of JSON:: parse.
If it’s nondeterministic, maybe you pass an invalid input buffer. Try running it with ASAN.
Источник
nlohmann::basic_json¶
Template parameters¶
Template parameter | Description | Derived type |
---|---|---|
ObjectType | type for JSON objects | object_t |
ArrayType | type for JSON arrays | array_t |
StringType | type for JSON strings and object keys | string_t |
BooleanType | type for JSON booleans | boolean_t |
NumberIntegerType | type for JSON integer numbers | number_integer_t |
NumberUnsignedType | type for JSON unsigned integer numbers | number_unsigned_t |
NumberFloatType | type for JSON floating-point numbers | number_float_t |
AllocatorType | type of the allocator to use | |
JSONSerializer | the serializer to resolve internal calls to to_json() and from_json() | json_serializer |
BinaryType | type for binary arrays | binary_t |
CustomBaseClass | extension point for user code | json_base_class_t |
Specializations¶
- json — default specialization
- ordered_json — specialization that maintains the insertion order of object keys
Iterator invalidation¶
Requirements¶
The class satisfies the following concept requirements:
Basic¶
- DefaultConstructible: JSON values can be default constructed. The result will be a JSON null value.
- MoveConstructible: A JSON value can be constructed from an rvalue argument.
- CopyConstructible: A JSON value can be copy-constructed from an lvalue expression.
- MoveAssignable: A JSON value can be assigned from an rvalue argument.
- CopyAssignable: A JSON value can be copy-assigned from an lvalue expression.
- Destructible: JSON values can be destructed.
Layout¶
- StandardLayoutType: JSON values have standard layout: All non-static data members are private and standard layout types, the class has no virtual functions or (virtual) base classes.
Library-wide¶
- EqualityComparable: JSON values can be compared with == , see operator== .
- LessThanComparable: JSON values can be compared with , see operator .
- Swappable: Any JSON lvalue or rvalue of can be swapped with any lvalue or rvalue of other compatible types, using unqualified function swap .
- NullablePointer: JSON values can be compared against std::nullptr_t objects which are used to model the null value.
Container¶
- Container: JSON values can be used like STL containers and provide iterator access.
- ReversibleContainer: JSON values can be used like STL containers and provide reverse iterator access.
Member types¶
- adl_serializer — the default serializer
- value_t — the JSON type enumeration
- json_pointer — JSON Pointer implementation
- json_serializer — type of the serializer to for conversions from/to JSON
- error_handler_t — type to choose behavior on decoding errors
- cbor_tag_handler_t — type to choose how to handle CBOR tags
- initializer_list_t — type for initializer lists of basic_json values
- input_format_t — type to choose the format to parse
- json_sax_t — type for SAX events
Exceptions¶
- exception — general exception of the basic_json class
- parse_error — exception indicating a parse error
- invalid_iterator — exception indicating errors with iterators
- type_error — exception indicating executing a member function with a wrong type
- out_of_range — exception indicating access out of the defined range
- other_error — exception indicating other library errors
Container types¶
Type | Definition |
---|---|
value_type | basic_json |
reference | value_type & |
const_reference | const value_type & |
difference_type | std :: ptrdiff_t |
size_type | std :: size_t |
allocator_type | AllocatorType basic_json > |
pointer | std :: allocator_traits allocator_type >:: pointer |
const_pointer | std :: allocator_traits allocator_type >:: const_pointer |
iterator | LegacyBidirectionalIterator |
const_iterator | constant LegacyBidirectionalIterator |
reverse_iterator | reverse iterator, derived from iterator |
const_reverse_iterator | reverse iterator, derived from const_iterator |
iteration_proxy | helper type for items function |
JSON value data types¶
- array_t — type for arrays
- binary_t — type for binary arrays
- boolean_t — type for booleans
- default_object_comparator_t — default comparator for objects
- number_float_t — type for numbers (floating-point)
- number_integer_t — type for numbers (integer)
- number_unsigned_t — type for numbers (unsigned)
- object_comparator_t — comparator for objects
- object_t — type for objects
- string_t — type for strings
Parser callback¶
- parse_event_t — parser event types
- parser_callback_t — per-element parser callback type
Member functions¶
- (constructor)
- (destructor)
- operator= — copy assignment
- array (static) — explicitly create an array
- binary (static) — explicitly create a binary array
- object (static) — explicitly create an object
Object inspection¶
Functions to inspect the type of a JSON value.
- type — return the type of the JSON value
- operator value_t — return the type of the JSON value
- type_name — return the type as string
- is_primitive — return whether type is primitive
- is_structured — return whether type is structured
- is_null — return whether value is null
- is_boolean — return whether value is a boolean
- is_number — return whether value is a number
- is_number_integer — return whether value is an integer number
- is_number_unsigned — return whether value is an unsigned integer number
- is_number_float — return whether value is a floating-point number
- is_object — return whether value is an object
- is_array — return whether value is an array
- is_string — return whether value is a string
- is_binary — return whether value is a binary array
- is_discarded — return whether value is discarded
Value access¶
Direct access to the stored value of a JSON value.
Element access¶
Access to the JSON value
- at — access specified element with bounds checking
- operator[] — access specified element
- value — access specified object element with default value
- front — access the first element
- back — access the last element
Источник
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
For relevant concepts of Jason, see Simple use of C++ Json Library.
1. Define JSON value type
If you want to create a JSON object in the following form:
{ "pi": 3.141, "happy": true, "name": "Niels", "nothing": null, "answer": { "everything": 42 }, "list": [1, 0, 2], "object": { "currency": "USD", "value": 42.99 } }
It is very convenient to use nlohmann library.
json j; //First, create an empty json object j["pi"] = 3.141; //Then initialize by name / value pair. At this time, the value corresponding to the name "pi" is 3.141 j["happy"] = true;//Assign the name "happy" to true j["name"] = "Niels";//Store the string "Niels" to "name" j["nothing"] = nullptr;//"nothing" corresponds to a null pointer j["answer"]["everything"] = 42;//Initializes the objects in the object j["list"] = { 1, 0, 2 };//Use the list initialization method to initialize the "list" array j["object"] = { {"currency", "USD"}, {"value", 42.99} };//Initialize object
Note: when constructing JSON objects in the above way, you do not need to tell the compiler which type you want to use. nlohmann will automatically perform implicit conversion.
If you want to explicitly define or express some situations, you can consider the following methods:
json empty_array_explicit = json::array();//Initializes an empty array in JSON format json empty_object_implicit = json({});//Implicitly define an empty object json empty_object_explicit = json::object();//Explicitly define an empty object json array_not_object = json::array({ {"currency", "USD"}, {"value", 42.99} });//Explicitly define and initialize a JSON array
2. Convert from STL container to json
The nlohmann library supports obtaining json objects (std::array, std::vector, std::deque, std::forward_list, std::list) from any sequence container initialization of STL. Their values can be used to construct json values.
std::set, std::multiset, std::unordered_ set, std::unordered_ The multiset Association container has the same usage and also saves its internal order.
In addition, std::map, std::multimap, std::unordered_map, std::unordered_multimap and nlohmann are also supported, but it should be noted that the Key is constructed as std::string to save.
std::vector<int> c_vector {1, 2, 3, 4}; json j_vec(c_vector); // [1, 2, 3, 4] std::deque<double> c_deque {1.2, 2.3, 3.4, 5.6}; json j_deque(c_deque); // [1.2, 2.3, 3.4, 5.6] std::list<bool> c_list {true, true, false, true}; json j_list(c_list); // [true, true, false, true] std::forward_list<int64_t> c_flist {12345678909876, 23456789098765, 34567890987654, 45678909876543}; json j_flist(c_flist); // [12345678909876, 23456789098765, 34567890987654, 45678909876543] std::array<unsigned long, 4> c_array {{1, 2, 3, 4}}; json j_array(c_array); // [1, 2, 3, 4] std::set<std::string> c_set {"one", "two", "three", "four", "one"}; json j_set(c_set); // only one entry for "one" is used // ["four", "one", "three", "two"] std::unordered_set<std::string> c_uset {"one", "two", "three", "four", "one"}; json j_uset(c_uset); // only one entry for "one" is used // maybe ["two", "three", "four", "one"] std::multiset<std::string> c_mset {"one", "two", "one", "four"}; json j_mset(c_mset); // both entries for "one" are used // maybe ["one", "two", "one", "four"] std::unordered_multiset<std::string> c_umset {"one", "two", "one", "four"}; json j_umset(c_umset); // both entries for "one" are used // maybe ["one", "two", "one", "four"] std::map<std::string, int> c_map { {"one", 1}, {"two", 2}, {"three", 3} }; json j_map(c_map); // {"one": 1, "three": 3, "two": 2 } std::unordered_map<const char*, double> c_umap { {"one", 1.2}, {"two", 2.3}, {"three", 3.4} }; json j_umap(c_umap); // {"one": 1.2, "two": 2.3, "three": 3.4} std::multimap<std::string, bool> c_mmap { {"one", true}, {"two", true}, {"three", false}, {"three", true} }; json j_mmap(c_mmap); // only one entry for key "three" is used // maybe {"one": true, "two": true, "three": true} std::unordered_multimap<std::string, bool> c_ummap { {"one", true}, {"two", true}, {"three", false}, {"three", true} }; json j_ummap(c_ummap); // only one entry for key "three" is used // maybe {"one": true, "two": true, "three": true}
When you use these json objects constructed through the STL container, you only need to arrange the STL container to use it in the same way.
3.string serialization and deserialization
Deserialization: recover JSON objects from byte sequences.
json j = "{ "happy": true, "pi": 3.141 }"_json; auto j2 = R"({"happy": true,"pi": 3.141})"_json;
Serialization: convert from JSON object to byte sequence.
std::string s = j.dump(); // {"happy":true,"pi":3.141} std::cout << j.dump(4) << std::endl;//Output as follows // { // "happy": true, // "pi": 3.141 // }
dump() returns the original string value stored in the JSON object.
4. Serialization and deserialization of stream
Standard output (std::cout) and standard input (std::cin)
json j; std::cin >> j;//Deserialize json objects from standard input std::cout << j;//Serialize json objects into standard output
Serializing json objects to local files or deserializing json objects from files stored locally is a very common operation. nlohmann is also very simple for this operation.
//Read a json file, and nlohmann will automatically parse the data in it std::ifstream i("file.json"); json j; i >> j; //Write json objects to local files in an easy to view manner std::ofstream o("pretty.json"); o << std::setw(4) << j << std::endl;
5. Any type conversion
Let me summarize the conversion methods for any type.
For any data type, you can convert it as follows:
namespace ns { //First define a structure struct person { std::string name; std::string address; int age; }; } ns::person p = {"Ned Flanders", "744 Evergreen Terrace", 60};//Define initialization p //Convert from structure to json object json j; j["name"] = p.name; j["address"] = p.address; j["age"] = p.age; //Convert from json object to structure ns::person p { j["name"].get<std::string>(), j["address"].get<std::string>(), j["age"].get<int>() };
However, such a method is inconvenient in scenes that often need to be converted. nlohmann provides a more convenient method:
using nlohmann::json; namespace ns { void to_json(json& j, const person& p) { j = json{{"name", p.name}, {"address", p.address}, {"age", p.age}}; } void from_json(const json& j, person& p) { j.at("name").get_to(p.name); j.at("address").get_to(p.address); j.at("age").get_to(p.age); } } // namespace ns ns::person p {"Ned Flanders", "744 Evergreen Terrace", 60}; json j = p; std::cout << j << std::endl; // {"address":"744 Evergreen Terrace","age":60,"name":"Ned Flanders"} // conversion: json -> person auto p2 = j.get<ns::person>(); // that's it assert(p == p2);
You only need to define the function to under the namespace where the person structure is located_ json () and from_json() can easily convert any type to json object and convert json to any object.
be careful:
- Function to_json() and from_json() is in the same namespace as the data type you defined;
- When you want to use these two functions in another file, you should correctly include the header file where it is located;
- From_ Use at() in JSON because it throws an error when you read a name that doesn’t exist.
When you can easily convert any type of data to json, you can easily serialize the json to local storage or deserialize it to memory, which is much more convenient than writing each byte yourself.
6. Explicit type conversion is recommended
Explicit type conversion is strongly recommended when retrieving data from json objects. For example:
std::string s1 = "Hello, world!"; json js = s1; auto s2 = js.get<std::string>(); //Not recommended std::string s3 = js; std::string s4; s4 = js; // Booleans bool b1 = true; json jb = b1; auto b2 = jb.get<bool>(); //Not recommended bool b3 = jb; bool b4; b4 = jb; // numbers int i = 42; json jn = i; auto f = jn.get<double>(); //Not recommended double f2 = jb; double f3; f3 = jb; // etc.
7. Convert JSON to binary format
Although JSON format is very commonly used, its disadvantages are also obvious. It is not a compact format and is not suitable for network transmission or local writing. JSON objects often need to be binary converted. nlohmann library supports a variety of binary formats, including BSON, CBOR, MessagePack and UBJSON
// create a JSON value json j = R"({"compact": true, "schema": 0})"_json; // serialize to BSON std::vector<std::uint8_t> v_bson = json::to_bson(j); // 0x1B, 0x00, 0x00, 0x00, 0x08, 0x63, 0x6F, 0x6D, 0x70, 0x61, 0x63, 0x74, 0x00, 0x01, 0x10, 0x73, 0x63, 0x68, 0x65, 0x6D, 0x61, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 // roundtrip json j_from_bson = json::from_bson(v_bson); // serialize to CBOR std::vector<std::uint8_t> v_cbor = json::to_cbor(j); // 0xA2, 0x67, 0x63, 0x6F, 0x6D, 0x70, 0x61, 0x63, 0x74, 0xF5, 0x66, 0x73, 0x63, 0x68, 0x65, 0x6D, 0x61, 0x00 // roundtrip json j_from_cbor = json::from_cbor(v_cbor); // serialize to MessagePack std::vector<std::uint8_t> v_msgpack = json::to_msgpack(j); // 0x82, 0xA7, 0x63, 0x6F, 0x6D, 0x70, 0x61, 0x63, 0x74, 0xC3, 0xA6, 0x73, 0x63, 0x68, 0x65, 0x6D, 0x61, 0x00 // roundtrip json j_from_msgpack = json::from_msgpack(v_msgpack); // serialize to UBJSON std::vector<std::uint8_t> v_ubjson = json::to_ubjson(j); // 0x7B, 0x69, 0x07, 0x63, 0x6F, 0x6D, 0x70, 0x61, 0x63, 0x74, 0x54, 0x69, 0x06, 0x73, 0x63, 0x68, 0x65, 0x6D, 0x61, 0x69, 0x00, 0x7D // roundtrip json j_from_ubjson = json::from_ubjson(v_ubjson);
If you need to write locally, you can use the following methods:
std::ofstream ofs(path, std::ios::out | std::ios::binary); const auto msgpack = nlohmann::json::to_msgpack(json); ofs.write(reinterpret_cast<const char*>(msgpack.data()), msgpack.size() * sizeof(uint8_t)); ofs.close();
8. Examples
This example shows how to save the member variables in the object locally and read the binary deserialized object locally.
#include <iostream> #include <nlohmann/json.hpp> #include <string> #include <map> #include <unordered_map> #include <fstream> using nlohmann::json; using namespace std; class TEST{ public: TEST(){} void SetValue(){ a = 1; b = 2; c = 3; d = 4; e = 5; f = "I love you!"; for (int i = 0; i < 10; ++i) { g.emplace_back(i); } for (int i = 0; i < 10; ++i) { h[to_string(i)] = static_cast<double>(i); } for (int i = 0; i < 10; ++i) { json json_temp(i); j[to_string(i)] = json_temp; } } json to_json(){ json json_temp; json_temp["a"] = a; json_temp["b"] = b; json_temp["c"] = c; json_temp["d"] = d; json_temp["e"] = e; json_temp["f"] = f; json_temp["g"] = g; json_temp["h"] = h; json_temp["j"] = j; return json_temp; } void from_json(const json& json_temp){ a = json_temp.at("a").get<int>(); b = json_temp.at("b").get<float>(); c = json_temp.at("c").get<double>(); d = json_temp.at("d").get<long>(); e = json_temp.at("e").get<long long>(); f = json_temp.at("f").get<string>(); g = json_temp.at("g").get<vector<int>>(); h = json_temp.at("h").get<map<string, double>>(); j = json_temp.at("j").get<unordered_map<string, json>>(); } public: int a; float b; double c; long d; long long e; string f; vector<int> g; map<string, double> h; unordered_map<string, json> j; }; int main(){ TEST test; test.SetValue(); json js = test.to_json(); const vector<uint8_t> message_pack = nlohmann::json::to_msgpack(js); ofstream ofs("./binary", std::ios::out | std::ios::binary | std::ios::trunc); ofs.write(reinterpret_cast<const char*>(message_pack.data()), message_pack.size()*sizeof(uint8_t)); ofs.close(); ifstream ifs("./binary", ios::binary | ios::in); std::vector<uint8_t> message_pack_1; while (true){ uint8_t buffer; ifs.read(reinterpret_cast<char*>(&buffer), sizeof(uint8_t)); if (ifs.eof()){ break; } message_pack_1.emplace_back(buffer); } ifs.close(); json js1 = nlohmann::json::from_msgpack(message_pack_1); TEST test1; test1.from_json(js1); cout << test1.a << endl; cout << test1.b << endl; cout << test1.c << endl; cout << test1.d << endl; cout << test1.e << endl; cout << test1.f << endl; return 0; }
Warm tip: although it is convenient to convert data into json objects, and then save and serialize them, when the data class is huge, reaching the level of millions or tens of millions, using this method again will consume a lot of time in constructing json objects. I tried a data of about 300M, which takes about tens of seconds to convert into json objects. It only takes 0.1 seconds for 300M megabytes of data to be written locally. So at this time, it’s better to directly operate the original data and write it locally. Don’t convert it into json objects. Although the algorithm will be a little troublesome, the speed is very fast.
9. Download JSON source code
Download address
Project address: nlohmann_json_cmake_fetchcontent/json.hpp at master · ArthurSonzogni/nlohmann_json_cmake_fetchcontent · GitHub
design goal
-
Intuitive syntax. In like Python In such a language, JSON is like a first-class data type. We used all the magic of modern C + + operators to achieve the same feeling in your code. Look at the following example and you’ll see what I mean.
-
Trivial integration. Our entire code consists of a single header file, json.hpp. That’s it. No libraries, no subprojects, no dependencies, no complex build systems. This class is written in ordinary C++11. In short, there is no need to adjust your compiler flags or project settings.
-
Rigorous testing. Our class has been 100% unit tested, including all abnormal behaviors. In addition, we confirmed with Valgrind and xxx that there was no memory leak. In addition, Google OSS fuzzy runs fuzzy tests on all parsers 24 / 7, and has efficiently performed billions of tests so far. In order to maintain high quality, the project follows (CII) best practices.
There are other aspects that are not important to us:
-
Memory efficiency. Each JSON object has the overhead of a pointer (the maximum size of the Union) and an enumeration element (1 byte). The default generalization uses the following C + + data types: std::string, corresponding string, int64_t,uint64_t or double corresponds to a number, std::map for an object, std::vector corresponds to an array, and bool corresponds to a Boolean value. However, you can template the generic class basic_json meets your needs.
-
Speed. There must be a faster JSON library outside. However, if your goal is to speed up development by adding JSON support with a single header file, this library is your choice.
Integration
json.hpp is the only file needed. Just add
#include <nlohmann/json.hpp> // for convenience using json = nlohmann::json;
You want to process json files and set it to support C + +.
You can further use the file include/nlohmann/json_fwd.hpp is used to forward declarations. json_ The installation of fwd.hpp (as part of the cmake installation steps) can be done by setting — djson_ MultipleHeaders =ON
example
In addition to the following examples, you may want to view the documentation, where each function contains a separate code example (for example, see empty()). All sample files can be compiled and executed by themselves (for example, the file empty. CPP).
JSON as a primary data type
Here are some examples to let you know how to use this class.
Suppose you want to create such a JSON object with this library:
{ "pi": 3.141, "happy": true, "name": "Niels", "nothing": null, "answer": { "everything": 42 }, "list": [1, 0, 2], "object": { "currency": "USD", "value": 42.99 } }
It can be written as follows:
// create an empty structure (null) json j; // add a number that is stored as double (note the implicit conversion of j to an object) j["pi"] = 3.141; // add a Boolean that is stored as bool j["happy"] = true; // add a string that is stored as std::string j["name"] = "Niels"; // add another null object by passing nullptr j["nothing"] = nullptr; // add an object inside the object j["answer"]["everything"] = 42; // add an array that is stored as std::vector (using an initializer list) j["list"] = { 1, 0, 2 }; // add another object (using an initializer list of pairs) j["object"] = { {"currency", "USD"}, {"value", 42.99} }; // instead, you could also write (which looks very similar to the JSON above) json j2 = { {"pi", 3.141}, {"happy", true}, {"name", "Niels"}, {"nothing", nullptr}, {"answer", { {"everything", 42} }}, {"list", {1, 0, 2}}, {"object", { {"currency", "USD"}, {"value", 42.99} }} };
Note that in all these cases, you never need to «tell» the compiler which JSON value type you want to use. If you want to clarify or express some edge cases, function json::array() and json::object() will help, as follows:
// a way to express the empty array [] json empty_array_explicit = json::array(); // ways to express the empty object {} json empty_object_implicit = json({}); json empty_object_explicit = json::object(); // a way to express an _array_ of key/value pairs [["currency", "USD"], ["value", 42.99]] json array_not_object = json::array({ {"currency", "USD"}, {"value", 42.99} });
Serialization / deserialization
To/from strings
You can add_ JSON to a string to create a JSON value (deserialization):
// create object from string literal json j = "{ "happy": true, "pi": 3.141 }"_json; // or even nicer with a raw string literal auto j2 = R"( { "happy": true, "pi": 3.141 } )"_json;
Please note that if not attached_ JSON suffix, the passed string text will not be parsed, but only used as JSON string value. That is, JSON J = «{» happy»: true, «pi»: 3.141}» only stores strings «{» happy»: true, «pi»: 3.141}», instead of parsing the actual object.
The above example can also use json::parse():
// parse explicitly auto j3 = json::parse("{ "happy": true, "pi": 3.141 }");
serialize
You can also get the string expression corresponding to a json object (serialization):
// explicit conversion to string std::string s = j.dump(); // {"happy":true,"pi":3.141} // serialization with pretty printing // pass in the amount of spaces to indent std::cout << j.dump(4) << std::endl; // { // "happy": true, // "pi": 3.141 // }
As shown above, adding the dump parameter can make the print result more beautiful.
Note the difference between serialization and assignment:
// store a string in a JSON value json j_string = "this is a string"; // Store a string in the json class // retrieve the string value // Gets the value of the internal string auto cpp_string = j_string.get<std::string>(); // retrieve the string value (alternative when an variable already exists) std::string cpp_string2; j_string.get_to(cpp_string2); // Assign the value of the internal string to cpp_string2? // retrieve the serialized value (explicit JSON serialization) // Explicitly serialize json objects into std::string std::string serialized_string = j_string.dump(); // output of original string // Output: get the value of the internal string, the value assigned to the string through the json object, and get the value of the internal string directly from json std::cout << cpp_string << " == " << cpp_string2 << " == " << j_string.get<std::string>() << 'n'; // output of serialized value // Overloaded the cout operator and directly output the value of the json object std::cout << j_string << " == " << serialized_string << std::endl;
The first is to store a string in the json class
The second is to get the value of the internal string.
The json object overloads the cout operator.
. dump() always returns a serialized value, and Get < STD:: String > () returns the originally stored string value.
be careful
The library only supports UTF-8. When you store strings of different encodings in the library, calling. dump() may throw an exception unless json::error_handler_t::replace or json::error_handler_t::ignore is used.
Note the library only supports UTF-8. When you store strings with
different encodings in the library, calling dump() may throw an
exception unless json::error_handler_t::replace or
json::error_handler_t::ignore are used as error handlers.
To/from streams (e.g. files, string streams)
You can also use stream to serialize and deserialize:
// deserialize from standard input json j; std::cin >> j; // serialize to standard output std::cout << j; // the setw manipulator was overloaded to set the indentation for pretty printing std::cout << std::setw(4) << j << std::endl;
The setw() operator has been overloaded and can be used to set indentation and better print format.
These operators apply to any subclass of std::istream or std::ostream. Here are some examples of files:
// read a JSON file // Get json object through file stream std::ifstream i("file.json"); json j; i >> j; // write prettified JSON to another file // Write the nice of the json object to the file std::ofstream o("pretty.json"); o << std::setw(4) << j << std::endl;
Note that if the exception bit is set to failbit, it is not suitable for this use case. This will cause the program to terminate because the noexcept specifier is in use.
Please note that setting the exception bit for failbit is inappropriate for this use case. It will result in program termination due to the noexcept specifier in use.
Read from iterator range
Resolved by a range iterator.
JSON can also be parsed from the iterator scope, that is, from any container accessible to the iterator, the value type is an integer type of 1, 2 or 4 bytes, which will be interpreted as UTF-8, UTF-16 and UTF-32 respectively. For example, an STD:: vector < STD:: uint8_ t> Or STD:: vector < STD:: uint16_ t>:
std::vector<std::uint8_t> v = {'t', 'r', 'u', 'e'}; json j = json::parse(v.begin(), v.end());
You may leave the iterators for the range [begin, end):
std::vector<std::uint8_t> v = {'t', 'r', 'u', 'e'}; json j = json::parse(v);
STL like access
We design JSON classes to behave like STL containers. In fact, it meets the requirements of reversible containers.
Add element:
// create an array using push_back json j; j.push_back("foo"); j.push_back(1); j.push_back(true); // also use emplace_back j.emplace_back(1.78);
Iterator traversal:
// iterate the array for (json::iterator it = j.begin(); it != j.end(); ++it) { std::cout << *it << 'n'; } // range-based for for (auto& element : j) { std::cout << element << 'n'; }
Get / set value
// getter/setter const auto tmp = j[0].get<std::string>(); j[1] = 42; bool foo = j.at(2);
Comparison:
// comparison j == "["foo", 42, true]"_json; // true
Other interfaces:
// other stuff j.size(); // 3 entries j.empty(); // false j.type(); // json::value_t::array j.clear(); // the array is empty again
Type extraction:
// convenience type checkers j.is_null(); j.is_boolean(); j.is_number(); j.is_object(); j.is_array(); j.is_string();
Create object:
// create an object json o; o["foo"] = 23; o["bar"] = false; o["baz"] = 3.141; // also use emplace o.emplace("weather", "sunny");
There are several other ways to access iterators:
// special iterator member functions for objects for (json::iterator it = o.begin(); it != o.end(); ++it) { std::cout << it.key() << " : " << it.value() << "n"; } // the same code as range for for (auto& el : o.items()) { std::cout << el.key() << " : " << el.value() << "n"; } // even easier with structured bindings (C++17) for (auto& [key, value] : o.items()) { std::cout << key << " : " << value << "n"; }
Find (exists):
// find an entry if (o.contains("foo")) { // there is an entry with key "foo" }
Return iterator lookup (return iterator):
// or via find and an iterator if (o.find("foo") != o.end()) { // there is an entry with key "foo" }
Find through count():
// or simpler using count() int foo_present = o.count("foo"); // 1 int fob_present = o.count("fob"); // 0
Delete:
// delete an entry o.erase("foo");
Convert from STL container
The values of any sequence container (std::array, std::vector, std::deque, std::forward_list, std::list) can be used to construct JSON values (for example, integers, floating-point numbers, Boolean values, string types, or STL containers described in this section), which can be used to create JSON arrays. Similarly, the same is true for associative containers (std::set, std::multiset, std::unordered_set, std::unordered_multiset), but in these cases, the order of array elements depends on the order of elements in their respective STL containers.
std::vector<int> c_vector {1, 2, 3, 4}; json j_vec(c_vector); // [1, 2, 3, 4] std::deque<double> c_deque {1.2, 2.3, 3.4, 5.6}; json j_deque(c_deque); // [1.2, 2.3, 3.4, 5.6] std::list<bool> c_list {true, true, false, true}; json j_list(c_list); // [true, true, false, true] std::forward_list<int64_t> c_flist {12345678909876, 23456789098765, 34567890987654, 45678909876543}; json j_flist(c_flist); // [12345678909876, 23456789098765, 34567890987654, 45678909876543] std::array<unsigned long, 4> c_array {{1, 2, 3, 4}}; json j_array(c_array); // [1, 2, 3, 4] std::set<std::string> c_set {"one", "two", "three", "four", "one"}; json j_set(c_set); // only one entry for "one" is used // ["four", "one", "three", "two"] std::unordered_set<std::string> c_uset {"one", "two", "three", "four", "one"}; json j_uset(c_uset); // only one entry for "one" is used // maybe ["two", "three", "four", "one"] std::multiset<std::string> c_mset {"one", "two", "one", "four"}; json j_mset(c_mset); // both entries for "one" are used // maybe ["one", "two", "one", "four"] std::unordered_multiset<std::string> c_umset {"one", "two", "one", "four"}; json j_umset(c_umset); // both entries for "one" are used // maybe ["one", "two", "one", "four"]
Similarly, any associated key value container (std::map, std::multimap, std::unordered_map, std::unordered_multimap), if its key can construct std::string And its value can be used to construct JSON values (see the above example), it can be used to create JSON objects. Note that in the case of Multimap, only one key is used in the JSON object, and the value depends on the internal order of the STL container.
std::map<std::string, int> c_map { {"one", 1}, {"two", 2}, {"three", 3} }; json j_map(c_map); // {"one": 1, "three": 3, "two": 2 } std::unordered_map<const char*, double> c_umap { {"one", 1.2}, {"two", 2.3}, {"three", 3.4} }; json j_umap(c_umap); // {"one": 1.2, "two": 2.3, "three": 3.4} std::multimap<std::string, bool> c_mmap { {"one", true}, {"two", true}, {"three", false}, {"three", true} }; json j_mmap(c_mmap); // only one entry for key "three" is used // maybe {"one": true, "two": true, "three": true} std::unordered_multimap<std::string, bool> c_ummap { {"one", true}, {"two", true}, {"three", false}, {"three", true} }; json j_ummap(c_ummap); // only one entry for key "three" is used // maybe {"one": true, "two": true, "three": true}
JSON Pointer and JSON Patch
JSON PATCH usage_ mojianpo Mo jianpo CSDN blog JSON PATCH usage_ mojianpo Mo jianpo CSDN blog
This library supports JSON pointers (RFC 6901) as an alternative to addressing structured value. Most importantly, JSON patch (RFC 6902) allows describing the difference between two JSON values — effectively allowing patch and difference operations known from Unix.
// a JSON value json j_original = R"({ "baz": ["one", "two", "three"], "foo": "bar" })"_json; // access members with a JSON pointer (RFC 6901) j_original["/baz/1"_json_pointer]; // "two" // a JSON patch (RFC 6902) json j_patch = R"([ { "op": "replace", "path": "/baz", "value": "boo" }, { "op": "add", "path": "/hello", "value": ["world"] }, { "op": "remove", "path": "/foo"} ])"_json; // apply the patch json j_result = j_original.patch(j_patch); // { // "baz": "boo", // "hello": ["world"] // } // calculate a JSON patch from two JSON values json::diff(j_result, j_original); // [ // { "op":" replace", "path": "/baz", "value": ["one", "two", "three"] }, // { "op": "remove","path": "/hello" }, // { "op": "add", "path": "/foo", "value": "bar" } // ]
Implicit conversion
Supported types can be implicitly converted to JSON values.
It is not recommended to use implicit conversion to convert values from JSON. You can turn OFF implicit conversion by defining JSON_USE_IMPLICIT_CONVERSIONS to 0 before including the json.hpp header file. If CMake is used, you can also do so by setting the option json_implicit conversions to OFF.
// strings std::string s1 = "Hello, world!"; json js = s1; auto s2 = js.get<std::string>(); // NOT RECOMMENDED std::string s3 = js; std::string s4; s4 = js; // Booleans bool b1 = true; json jb = b1; auto b2 = jb.get<bool>(); // NOT RECOMMENDED bool b3 = jb; bool b4; b4 = jb; // numbers int i = 42; json jn = i; auto f = jn.get<double>(); // NOT RECOMMENDED double f2 = jb; double f3; f3 = jb; // etc.
Note that char type is not automatically converted to JSON string, but to integer. Conversion to string must be explicitly specified:
char ch = 'A'; // ASCII value 65 json j_default = ch; // stores integer number 65 json j_string = std::string(1, ch); // stores string "A"
Arbitrary type conversion
Each type can be serialized in JSON, not just STL containers and scalar types. Usually, you will do something similar:
namespace ns { // a simple struct to model a person struct person { std::string name; std::string address; int age; }; } ns::person p = {"Ned Flanders", "744 Evergreen Terrace", 60}; // convert to JSON: copy each value into the JSON object json j; j["name"] = p.name; j["address"] = p.address; j["age"] = p.age; // ... // convert from JSON: copy each value from the JSON object ns::person p { j["name"].get<std::string>(), j["address"].get<std::string>(), j["age"].get<int>() };
It works, but it’s troublesome… There’s a better way:
// create a person ns::person p {"Ned Flanders", "744 Evergreen Terrace", 60}; // conversion: person -> json json j = p; std::cout << j << std::endl; // {"address":"744 Evergreen Terrace","age":60,"name":"Ned Flanders"} // conversion: json -> person auto p2 = j.get<ns::person>(); // that's it assert(p == p2);
Basic Usage
To make this work with your type, you only need to provide two functions:
using nlohmann::json; namespace ns { void to_json(json& j, const person& p) { j = json{{"name", p.name}, {"address", p.address}, {"age", p.age}}; } void from_json(const json& j, person& p) { j.at("name").get_to(p.name); j.at("address").get_to(p.address); j.at("age").get_to(p.age); } } // namespace ns
That’s it! When calling the JSON constructor and your type, the custom to_json method will be called automatically. Similarly, when calling get < your_type > () or get_to (your_type &), the from_json method will be called.