Search code examples
c++carraysjsonrapidjson

Convert mixed JSON-Number-Array to int, uint, float using lib rapidjson


As I understood this char* is a valid json-string.

const char* json = { "array":[14, -15, 3.17], "array_type": ["uint", "int", "float"] }

All numbers in the array shall be 4 bytes.

How could one loop through the array using rapidjson?

This is my code so far:

#include "rapidjson/document.h"

using namespace rapidjson;

int main(void) 
{

int i_val; unsigned int ui_val; float f_val;
const char* json = "{ \"array\":[14, -15, 3.17], \"array_type\" : [\"uint\", \"int\", \"float\"] }";

Document d;

d.Parse<0>(json);
Value& a = d["array"]; 
Value& at = d["array_type"];

for (SizeType i = 0; i<a.Size(); i++)
{
    if (a[i].IsInt() && (std::string)at[i].GetString() == "int")
    {
        i_val = a[i].GetInt();
        //Do anything
    }
    if (a[i].IsUint() && (std::string)at[i].GetString() == "uint")
    {
        ui_val = a[i].GetUint();
        //Do anything
    }
    if (a[i].IsDouble() && (std::string)at[i].GetString() == "float")
    {
        f_val = (float)a[i].GetDouble();
        //Do anything
    }
}//end for

    return 0;
}

ERROR:

TestApp: /workspace/TestApp/src/include/rapidjson/document.h:1277: rapidjson::GenericValue<Encoding, Allocator>& rapidjson::GenericValue<Encoding, Allocator>::operator[](rapidjson::SizeType) [with Encoding = rapidjson::UTF8<>; Allocator = rapidjson::MemoryPoolAllocator<>; rapidjson::SizeType = unsigned int]: Assertion `index < data_.a.size' failed.

The code crashes at the function a.Size(), when it is executed after GetDouble. How could one solve this?

I know the last "if" is wrong and thats probably why the program crashes. Double is 8 bytes and the SizeType is 4 bytes by default.

Is there a solution to loop though the array?? If not I also would be good with other libs.. I need to transport these three different types of values by json. By the way the length of the array could be 1 to 500.

(There is no GetFloat() function.)

Thanks for any kind of help. Regards


Solution

  • You can use JSONLint to validate json string. Your example fixed:

    int i_val; unsigned int ui_val; float f_val;
    const char* json = "{ \"array\":[14, -15, 3.17], \"array_type\" : [\"uint\", \"int\", \"float\"] }";
    rapidjson::Document d;
    
    d.Parse<0>(json);
    rapidjson::Value& a = d["array"]; 
    rapidjson::Value& at = d["array_type"];
    
    for (rapidjson::SizeType i = 0; i<a.Size(); i++)
    {
        if (a[i].IsInt() && (std::string)at[i].GetString() == "int")
        {
            i_val = a[i].GetInt();
            //Do anything
        }
        if (a[i].IsUint() && (std::string)at[i].GetString() == "uint")
        {
            ui_val = a[i].GetUint();
            //Do anything
        }
        if (a[i].IsDouble() && (std::string)at[i].GetString() == "float")
        {
            f_val = (float)a[i].GetDouble();
            //Do anything
        }
    }