Try it yourself with our free Toml Formatter tool — runs entirely in your browser, no signup needed.

How to Parse TOML in C++

How to parse TOML in C++

=====================================

Parsing TOML (Tom's Obvious, Minimal Language) files in C++ can be a crucial task in various applications, such as configuration management, data storage, and more. TOML is a lightweight, human-readable format that is easy to work with, but parsing it efficiently and correctly requires some expertise. In this guide, we'll walk you through the process of parsing TOML in C++ using the toml++ library, covering common use cases, edge cases, and performance tips.

Quick Example


Here's a minimal example that demonstrates how to parse a TOML file using toml++:

#include <toml++/toml.h>
#include <iostream>

int main() {
    std::string toml_str = R"(
        title = "Example"
        [owner]
        name = "John Doe"
        dob = 1979-05-27
    )";

    toml::table tbl;
    try {
        tbl = toml::parse(toml_str);
    } catch (const toml::parse_error& e) {
        std::cerr << "Error parsing TOML: " << e.what() << std::endl;
        return 1;
    }

    std::cout << "Title: " << tbl["title"].value_or<std::string>() << std::endl;
    std::cout << "Owner Name: " << tbl["owner"]["name"].value_or<std::string>() << std::endl;
    std::cout << "Owner DOB: " << tbl["owner"]["dob"].value_or<int>() << std::endl;

    return 0;
}

To use this code, you'll need to install the toml++ library using your package manager (e.g., apt-get install libtoml++-dev on Ubuntu-based systems) or by cloning the repository and building it manually.

Step-by-Step Breakdown


Let's break down the example code:

  1. We include the necessary headers: toml++/toml.h for TOML parsing and iostream for input/output operations.
  2. We define a sample TOML string toml_str containing a simple configuration.
  3. We create an empty toml::table object tbl to store the parsed data.
  4. We attempt to parse the TOML string using toml::parse(toml_str). If parsing fails, we catch the toml::parse_error exception and print an error message.
  5. We access the parsed data using the tbl object's value_or method, which returns the value associated with a given key or a default value if the key is missing.

Handling Edge Cases


Here are some common edge cases to consider:

Empty/Null Input

When dealing with empty or null input, you should check for these conditions before attempting to parse the TOML data:

if (toml_str.empty()) {
    std::cerr << "Error: Empty TOML input." << std::endl;
    return 1;
}

Invalid Input

To handle invalid TOML input, you can catch the toml::parse_error exception and provide a meaningful error message:

try {
    tbl = toml::parse(toml_str);
} catch (const toml::parse_error& e) {
    std::cerr << "Error parsing TOML: " << e.what() << std::endl;
    return 1;
}

Large Input

When working with large TOML files, you may need to consider memory constraints. You can use the toml::parse_stream function to parse the input in chunks:

std::ifstream file("large_toml_file.toml");
toml::parse_stream(file, tbl);

Unicode/Special Characters

TOML supports Unicode characters, but you should ensure that your C++ code can handle them correctly. The toml++ library uses UTF-8 encoding by default, so you can work with Unicode characters without additional setup.

Common Mistakes


Here are some common mistakes developers make when parsing TOML in C++:

Mistake 1: Not checking for parsing errors

// WRONG
tbl = toml::parse(toml_str);

// CORRECT
try {
    tbl = toml::parse(toml_str);
} catch (const toml::parse_error& e) {
    std::cerr << "Error parsing TOML: " << e.what() << std::endl;
    return 1;
}

Mistake 2: Not handling empty or null input

// WRONG
tbl = toml::parse(toml_str);

// CORRECT
if (toml_str.empty()) {
    std::cerr << "Error: Empty TOML input." << std::endl;
    return 1;
}
tbl = toml::parse(toml_str);

Mistake 3: Not using the correct data type

// WRONG
std::string dob = tbl["owner"]["dob"].value_or<std::string>();

// CORRECT
int dob = tbl["owner"]["dob"].value_or<int>();

Performance Tips


Here are some performance tips for parsing TOML in C++:

  1. Use toml::parse_stream for large inputs: When working with large TOML files, use toml::parse_stream to parse the input in chunks, reducing memory usage and improving performance.
  2. Use std::string_view for input: When passing TOML input to the toml::parse function, use std::string_view instead of std::string to avoid unnecessary string copies.
  3. Avoid unnecessary parsing: Only parse the TOML data when necessary, and consider caching the parsed data to avoid repeated parsing.

FAQ


Q: What is the difference between toml::parse and toml::parse_stream?

A: toml::parse parses the entire input at once, while toml::parse_stream parses the input in chunks, reducing memory usage for large inputs.

Q: How do I handle Unicode characters in TOML input?

A: The toml++ library uses UTF-8 encoding by default, so you can work with Unicode characters without additional setup.

Q: What is the recommended way to handle parsing errors?

A: Catch the toml::parse_error exception and provide a meaningful error message.

Q: Can I use toml++ with C++11/C++14?

A: Yes, toml++ supports C++11 and C++14.

Q: How do I install the toml++ library?

A: You can install toml++ using your package manager (e.g., apt-get install libtoml++-dev on Ubuntu-based systems) or by cloning the repository and building it manually.

AI agent tools available. The CodeTidy MCP Server gives Claude, Cursor, and other AI agents access to 60+ developer tools. One command: npx @codetidy/mcp