skip to Main Content

I’m trying to parse .json in C++ using nlohmann/json library on Ubuntu but during compilation it fails every time and I can’t understand why it’s happening like this, help!

yt_dlp_cpp.hpp

#pragma once

#ifndef YT_DLP_CPP_HPP
#define YT_DLP_CPP_HPP

#include <string>
#include <vector>

namespace yt_dlp_cpp
{
    struct format_info
    {
        std::string format_id, format_note, ext;
        size_t width, height;
    };

    class yt_dlp
    {
      public:
        yt_dlp();

        yt_dlp(const std::string &url);

        void set_url(const std::string &url);

        const std::vector<format_info> get_formats() const;

      private:
        struct info
        {
            std::string url;
        } info;

        std::vector<format_info> formats;
    };
} // namespace yt_dlp_cpp

#endif // YT_DLP_CPP_HPP

yt_dlp_cpp.cpp

#include <boost/process.hpp>
#include <memory>

#include "nlohmann/json.hpp"
#include "yt_dlp_cpp.hpp"

std::unique_ptr<nlohmann::json> yt_dlp_json_info;

inline void yt_dlp_parse_json_info(const std::string &url)
{
    boost::process::ipstream pipe_stream;
    boost::process::child c(
        "yt-dlp --no-playlist --skip-download --dump-json " + url,
        boost::process::std_out > pipe_stream
    );

    std::string temp_line, output;

    while (std::getline(pipe_stream, temp_line)) output += temp_line;

    c.wait();

    yt_dlp_json_info =
        std::make_unique<nlohmann::json>(nlohmann::json::parse(output));
}

inline void yt_dlp_init_formats(std::vector<yt_dlp_cpp::format_info> &formats)
{
    for (const auto &i : yt_dlp_json_info->at("formats"))
    {
        formats.push_back(
            {i["format_id"], i["format_note"], i["ext"],
             i["width"].get<size_t>(), i["height"].get<size_t>()}
        );
    }
}

yt_dlp_cpp::yt_dlp::yt_dlp() {}

yt_dlp_cpp::yt_dlp::yt_dlp(const std::string &url) { set_url(url); }

void yt_dlp_cpp::yt_dlp::set_url(const std::string &url)
{
    yt_dlp_parse_json_info(url);
    yt_dlp_init_formats(formats);
    info.url = url;
}

const std::vector<yt_dlp_cpp::format_info>
    yt_dlp_cpp::yt_dlp::get_formats() const
{
    return formats;
}

main.cpp

#include <iostream>

#include "yt_dlp_cpp.hpp"

using namespace std;

int main()
{
    yt_dlp_cpp::yt_dlp yt_dlp("https://youtu.be/Sab6wfnmTcY?si=wE-kXRdHtlNLxVE0"
    );

    for (const auto &i : yt_dlp.get_formats()) cout << i.ext << endl;

    return EXIT_SUCCESS;
}

So I compiled this code using xmake and every time I’m getting compilation error…

Compilation error

main: nlohmann/json.hpp:21450: const value_type& nlohmann::json_abi_v3_11_3::basic_json<ObjectType, ArrayType, StringType, BooleanType, NumberIntegerType, NumberUnsignedType, NumberFloatType, AllocatorType, JSONSerializer, BinaryType, CustomBaseClass>::operator[](const typename nlohmann::json_abi_v3_11_3::basic_json<ObjectType, ArrayType, StringType, BooleanType, NumberIntegerType, NumberUnsignedType, NumberFloatType, AllocatorType, JSONSerializer, BinaryType, CustomBaseClass>::object_t::key_type&) const [with ObjectType = std::map; ArrayType = std::vector; StringType = std::__cxx11::basic_string<char>; BooleanType = bool; NumberIntegerType = long int; NumberUnsignedType = long unsigned int; NumberFloatType = double; AllocatorType = std::allocator; JSONSerializer = nlohmann::json_abi_v3_11_3::adl_serializer; BinaryType = std::vector<unsigned char>; CustomBaseClass = void; nlohmann::json_abi_v3_11_3::basic_json<ObjectType, ArrayType, StringType, BooleanType, NumberIntegerType, NumberUnsignedType, NumberFloatType, AllocatorType, JSONSerializer, BinaryType, CustomBaseClass>::const_reference = const nlohmann::json_abi_v3_11_3::basic_json<>&; typename nlohmann::json_abi_v3_11_3::basic_json<ObjectType, ArrayType, StringType, BooleanType, NumberIntegerType, NumberUnsignedType, NumberFloatType, AllocatorType, JSONSerializer, BinaryType, CustomBaseClass>::object_t::key_type = std::__cxx11::basic_string<char>; nlohmann::json_abi_v3_11_3::basic_json<ObjectType, ArrayType, StringType, BooleanType, NumberIntegerType, NumberUnsignedType, NumberFloatType, AllocatorType, JSONSerializer, BinaryType, CustomBaseClass>::object_t = std::map<std::__cxx11::basic_string<char>, nlohmann::json_abi_v3_11_3::basic_json<>, std::less<void>, std::allocator<std::pair<const std::__cxx11::basic_string<char>, nlohmann::json_abi_v3_11_3::basic_json<> > > >]: Assertion `it != m_data.m_value.object->end()' failed.
error: execv(/home/sasha/yt_dlp_cpp/build/linux/x86_64/debug/main ) failed(-1)

2

Answers


  1. Chosen as BEST ANSWER

    Okay, I found a solution to this... Every time scanning JSON I need to just check if a variable key exists in it...


  2. Too large for a comment, so try add it here instead.

    The assert comes from this function:

    /// @brief access specified object element
    /// @sa https://json.nlohmann.me/api/basic_json/operator%5B%5D/
    const_reference operator[](const typename object_t::key_type& key) const
    {
        // const operator[] only works for objects
        if (JSON_HEDLEY_LIKELY(is_object()))
        {
            auto it = m_data.m_value.object->find(key);
            JSON_ASSERT(it != m_data.m_value.object->end());  // line 21450
            return it->second;
        }
    
        JSON_THROW(type_error::create(305, detail::concat("cannot use operator[] with a string argument with ", type_name()), this));
    }
    

    Seems like it is looking for a key, and it is just not there.

    Alternatively, the code tries to add the key using container[key] = value;, but the container is const.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search