FileWatch,观测文件变化,源码地址:https://github.com/ThomasMonkman/filewatch
nlohmann::json,json封装解析,源码地址:https://github.com/nlohmann/json
optionparser,解析选项,源码地址:https://optionparser.sourceforge.net/
以上介绍的这三个工具都是我在学习FastDDS过程中看到的。他们的使用非常简单,都只有一个头文件。下面简单介绍一下如何使用:
FileWatch
#include <functional> #include "FileWatch.hpp" using FileWatchHandle = std::unique_ptr<filewatch::FileWatch<std::string>>; void watch() { std::cout << "watch" << std::endl; } int main() { std::function<void()> callback = watch; (new filewatch::FileWatch<std::string>("d:\\test.txt", [callback](const std::string& /*path*/, const filewatch::Event change_type) { switch (change_type) { case filewatch::Event::modified: callback(); break; default: // No-op break; } })); getchar(); return 0; }
只需要设置一个文件路径和一个回调函数,当这个文件改动时,就会触发回调函数。这个可以做一些热更新配置的功能,当配置文件变动时,无需重启软件,就能读取新的配置。
nlohmann::json
#include "json.hpp" #include <iostream> using Info = nlohmann::json; int main() { Info info; std::cout << info.size() << std::endl; info["a"] = "b"; std::cout << info["a"] << std::endl; auto iter = info.find("a"); if (iter == info.end()) { std::cout << "not found" << std::endl; } else { std::cout << *iter << std::endl; } std::string s = R"({ "name" : "nick", "credits" : "123", "ranking" : 1 })"; auto j = nlohmann::json::parse(s); std::cout << j["name"] << std::endl; std::string ss = j.dump(); std::cout << "ss : " << ss << std::endl; Info j1; Info j2 = nlohmann::json::object(); Info j3 = nlohmann::json::array(); std::cout << j1.is_object() << std::endl; std::cout << j1.type_name() << std::endl; std::cout << j2.is_object() << std::endl; std::cout << j2.is_array() << std::endl; Info infoo{ {"name", "darren"}, {"credits", 123}, {"ranking", 1} }; std::cout << infoo["name"] << std::endl; std::cout << infoo.type_name() << std::endl; //遍历 for (auto iter = infoo.begin(); iter != infoo.end(); iter++) { std::cout << iter.key() << " : " << iter.value() << std::endl; //std::cout << iter.value() << std::endl; //std::cout << *iter << std::endl; } system("pause"); return 0; }
更多内容可以参考csdn:https://blog.csdn.net/gaoyuelon/article/details/131482372?fromshare=blogdetail
optionparser
#include "optionparser.h" struct Arg : public option::Arg { static void print_error( const char* msg1, const option::Option& opt, const char* msg2) { fprintf(stderr, "%s", msg1); fwrite(opt.name, opt.namelen, 1, stderr); fprintf(stderr, "%s", msg2); } static option::ArgStatus Unknown( const option::Option& option, bool msg) { if (msg) { print_error("Unknown option '", option, "'\n"); } return option::ARG_ILLEGAL; } static option::ArgStatus Required( const option::Option& option, bool msg) { if (option.arg != 0 && option.arg[0] != 0) { return option::ARG_OK; } if (msg) { print_error("Option '", option, "' requires an argument\n"); } return option::ARG_ILLEGAL; } static option::ArgStatus Numeric( const option::Option& option, bool msg) { char* endptr = 0; if (option.arg != nullptr) { strtol(option.arg, &endptr, 10); if (endptr != option.arg && *endptr == 0) { return option::ARG_OK; } } if (msg) { print_error("Option '", option, "' requires a numeric argument\n"); } return option::ARG_ILLEGAL; } template<long min = 0, long max = std::numeric_limits<long>::max()> static option::ArgStatus NumericRange( const option::Option& option, bool msg) { static_assert(min <= max, "NumericRange: invalid range provided."); char* endptr = 0; if (option.arg != nullptr) { long value = strtol(option.arg, &endptr, 10); if (endptr != option.arg && *endptr == 0 && value >= min && value <= max) { return option::ARG_OK; } } if (msg) { std::ostringstream os; os << "' requires a numeric argument in range [" << min << ", " << max << "]" << std::endl; print_error("Option '", option, os.str().c_str()); } return option::ARG_ILLEGAL; } static option::ArgStatus String( const option::Option& option, bool msg) { if (option.arg != 0) { return option::ARG_OK; } if (msg) { print_error("Option '", option, "' requires an argument\n"); } return option::ARG_ILLEGAL; } }; enum optionIndex { UNKNOWN_OPT, HELP, SAMPLES, INTERVAL, ENVIRONMENT }; const option::Descriptor usage[] = { { UNKNOWN_OPT, 0, "", "", Arg::None, "Usage: HelloWorldExample <publisher|subscriber>\n\nGeneral options:" }, { HELP, 0, "h", "help", Arg::None, " -h \t--help \tProduce help message." }, { UNKNOWN_OPT, 0, "", "", Arg::None, "\nPublisher options:"}, { SAMPLES, 0, "s", "samples", Arg::NumericRange<>, " -s <num>, \t--samples=<num> \tNumber of samples (0, default, infinite)." }, { INTERVAL, 0, "i", "interval", Arg::NumericRange<>, " -i <num>, \t--interval=<num> \tTime between samples in milliseconds (Default: 100)." }, { ENVIRONMENT, 0, "e", "env", Arg::None, " -e \t--env \tLoad QoS from environment." }, { 0, 0, 0, 0, 0, 0 } }; int main(int argc, char **argv) { argc -= (argc > 0); argv += (argc > 0); // skip program name argv[0] if present option::Stats stats(true, usage, argc, argv); std::vector<option::Option> options(stats.options_max); std::vector<option::Option> buffer(stats.buffer_max); option::Parser parse(true, usage, argc, argv, &options[0], &buffer[0]); try { if (parse.error()) { throw 1; } if (options[HELP] || options[UNKNOWN_OPT]) { throw 1; } // For backward compatibility count and sleep may be given positionally if (parse.nonOptionsCount() > 3 || parse.nonOptionsCount() == 0) { throw 2; } // Decide between publisher or subscriber const char* type_name = parse.nonOption(0); // make sure is the first option. // type_name and buffer[0].name reference the original command line char array // type_name must precede any other arguments in the array. // Note buffer[0].arg may be null for non-valued options and is not reliable for // testing purposes. if (parse.optionsCount() && type_name >= buffer[0].name) { throw 2; } if (strcmp(type_name, "publisher") == 0) { std::cout << "publisher" << std::endl; } else if (strcmp(type_name, "subscriber") == 0) { std::cout << "subscriber" << std::endl; } else { throw 2; } } catch (int error) { if (error == 2) { std::cerr << "ERROR: first argument must be <publisher|subscriber> followed by - or -- options" << std::endl; } option::printUsage(fwrite, stdout, usage); return error; } getchar(); return 0; }
简单好用的工具能给我们工作带来很多便利,希望这些工具对你有用~