介绍几种使用工具

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;
}

在这里插入图片描述
简单好用的工具能给我们工作带来很多便利,希望这些工具对你有用~

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

高二的笔记

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值