C++自定义一个toJson函数

287 阅读4分钟

提供一个std::string toJson(const std::setstd::string &set) 方法

@radix-vue

要将 std::set<std::string> 转换为 JSON 字符串,可以使用标准库中的一些工具。例如,可以构建一个有效的 JSON 数组字符串来表示集合中的每个字符串项。

以下是一个实现,将 std::set<std::string> 转换为一个 JSON 字符串:

cpp
复制代码
#include <iostream>
#include <set>
#include <string>
#include <sstream>

// 将 std::set<std::string> 转换为 JSON 字符串
std::string toJson(const std::set<std::string> &inputSet) {
    std::ostringstream oss;
    oss << "[";

    for (auto it = inputSet.begin(); it != inputSet.end(); ++it) {
        // 添加元素到 JSON 字符串中,并进行转义处理
        oss << """ << *it << """;
        if (std::next(it) != inputSet.end()) {
            oss << ", ";
        }
    }

    oss << "]";
    return oss.str();
}

int main() {
    std::set<std::string> exampleSet = {"apple", "banana", "cherry"};
    std::string jsonStr = toJson(exampleSet);
    std::cout << "JSON string: " << jsonStr << std::endl;
    return 0;
}

说明

  1. 包含头文件

    • #include <iostream>
    • #include <set>
    • #include <string>
    • #include <sstream>
  2. toJson 函数

    • 接受 const std::set<std::string>& 类型的参数(集合)。
    • 使用 std::ostringstream 来构建最终的 JSON 字符串。
    • 使用迭代器迭代集合中的每个元素,将其转换为 JSON 格式并添加到 oss 中,并适当地进行字符串格式化和转义(例如添加双引号)。
    • 将所有元素用逗号分隔,并确保最后一个元素后不额外添加逗号。
    • 返回构建的 JSON 字符串。
  3. main 函数

    • 创建一个 std::set<std::string> 的示例。
    • 调用 toJson 将集合转换为 JSON 字符串,并输出结果。

处理特殊字符

在上面的简单实现中,字符串中的特殊字符(如双引号或反斜杠)没有被转义。如果需要处理更多特殊字符,可以扩展字符串转义逻辑:

cpp
复制代码
#include <iostream>
#include <set>
#include <string>
#include <sstream>

// 转义 JSON 字符串中的特殊字符
std::string escapeJsonString(const std::string &input) {
    std::ostringstream escaped;
    for (const char c : input) {
        switch (c) {
            case '"':  escaped << "\""; break;
            case '\': escaped << "\\"; break;
            case '\b': escaped << "\b"; break;
            case '\f': escaped << "\f"; break;
            case '\n': escaped << "\n"; break;
            case '\r': escaped << "\r"; break;
            case '\t': escaped << "\t"; break;
            default:
                if ('\x00' <= c && c <= '\x1f') {
                    escaped << "\u"
                            << std::hex << std::setw(4) << std::setfill('0') << static_cast<int>(c);
                } else {
                    escaped << c;
                }
        }
    }
    return escaped.str();
}

// 将 std::set<std::string> 转换为 JSON 字符串
std::string toJson(const std::set<std::string> &inputSet) {
    std::ostringstream oss;
    oss << "[";

    for (auto it = inputSet.begin(); it != inputSet.end(); ++it) {
        // 添加转义后的元素到 JSON 字符串中
        oss << """ << escapeJsonString(*it) << """;
        if (std::next(it) != inputSet.end()) {
            oss << ", ";
        }
    }

    oss << "]";
    return oss.str();
}

int main() {
    std::set<std::string> exampleSet = {"apple", "banana", "cherry", ""special"", "\characters\"};
    std::string jsonStr = toJson(exampleSet);
    std::cout << "JSON string: " << jsonStr << std::endl;
    return 0;
}

示例说明

  1. escapeJsonString 函数

    • 遍历输入字符串的每个字符,检查并转义特殊字符。
    • 对于标准的控制字符(如双引号、反斜杠、换行等),使用相应的转义序列。
    • 对于其余的控制字符(例如不可见的低级ASCII字符),使用 Unicode 转义 (\uXXXX)。
  2. 更新的 toJson 函数

    • 使用 escapeJsonString 函数来转义集合中的每个字符串元素,然后再添加到 oss 流对象中。

这段代码能够更好地处理特殊字符,使生成的 JSON 字符串更加符合标准JSON格式。

上面的setw和setfill找不到,标红了

@radix-vue

使用 std::setw 和 std::setfill 需要包含 <iomanip> 头文件。这两个操纵器用于格式化输出,例如在 std::ostringstream 输出时设置宽度和填充字符。

这是修正后的代码,确保包含 <iomanip> 头文件:

cpp
复制代码
#include <iostream>
#include <set>
#include <string>
#include <sstream>
#include <iomanip> // 需要包含这个头文件

// 转义 JSON 字符串中的特殊字符
std::string escapeJsonString(const std::string &input) {
    std::ostringstream escaped;
    for (const char c : input) {
        switch (c) {
            case '"':  escaped << "\""; break;
            case '\': escaped << "\\"; break;
            case '\b': escaped << "\b"; break;
            case '\f': escaped << "\f"; break;
            case '\n': escaped << "\n"; break;
            case '\r': escaped << "\r"; break;
            case '\t': escaped << "\t"; break;
            default:
                if ('\x00' <= c && c <= '\x1f') {
                    escaped << "\u"
                            << std::hex << std::setw(4) << std::setfill('0') << static_cast<int>(c);
                } else {
                    escaped << c;
                }
        }
    }
    return escaped.str();
}

// 将 std::set<std::string> 转换为 JSON 字符串
std::string toJson(const std::set<std::string> &inputSet) {
    std::ostringstream oss;
    oss << "[";

    for (auto it = inputSet.begin(); it != inputSet.end(); ++it) {
        // 添加转义后的元素到 JSON 字符串中
        oss << """ << escapeJsonString(*it) << """;
        if (std::next(it) != inputSet.end()) {
            oss << ", ";
        }
    }

    oss << "]";
    return oss.str();
}

int main() {
    std::set<std::string> exampleSet = {"apple", "banana", "cherry", ""special"", "\characters\"};
    std::string jsonStr = toJson(exampleSet);
    std::cout << "JSON string: " << jsonStr << std::endl;
    return 0;
}

代码解释

  1. 包含头文件

    • #include <iostream>:用于标准输入输出。
    • #include <set>:用于使用 std::set
    • #include <string>:用于使用 std::string
    • #include <sstream>:用于 std::ostringstream
    • #include <iomanip>:用于 std::setw 和 std::setfill
  2. escapeJsonString 函数

    • 转义输入 JSON 字符串中的特殊字符。
    • 使用 std::hex 设置数字输出为十六进制格式。
    • 使用 std::setw(4) 将宽度设置为4,并用 std::setfill('0') 进行填充,确保 Unicode 转义字符符合 \uXXXX 格式。
  3. toJson 函数

    • 接受 const std::set<std::string>& 类型的输入集合。
    • 使用 std::ostringstream 来构建 JSON 字符串。
    • 转义集合中的每个字符串元素并添加到输出流中,确保最后一个元素后不添加额外的逗号。

使用方法

将上述代码保存为一个 .cpp 文件,例如 to_json.cpp,然后使用以下命令编译并运行程序:

sh
复制代码
g++ -o to_json to_json.cpp
./to_json

这样可以确保程序正常运行,并输出正确的 JSON 字符串格式。