C++ c++;检查varargs是否包含
是否有一个简单的api(没有循环)来检查varargs是否包含一些值(char*) 如果没有简单的API,如何在没有任何参数计数的情况下进行迭代 我的方法应该能够根据配置IP过滤日志,因此我需要检查其中一个参数是否为10.3.2.2(某些配置IP)C++ c++;检查varargs是否包含,c++,C++,是否有一个简单的api(没有循环)来检查varargs是否包含一些值(char*) 如果没有简单的API,如何在没有任何参数计数的情况下进行迭代 我的方法应该能够根据配置IP过滤日志,因此我需要检查其中一个参数是否为10.3.2.2(某些配置IP) 还有很多其他的电话。在过滤器中,我想检查其中一个参数值是否为“10.1.1.1”(例如),所以不要记录它。没有任何语法糖分可以这样做,因为没有通用的方法来知道varargs的类型。如果不知道类型,就无法获取它们的值。因此,您必须根据函数如何知道其参数
还有很多其他的电话。在过滤器中,我想检查其中一个参数值是否为“10.1.1.1”(例如),所以不要记录它。没有任何语法糖分可以这样做,因为没有通用的方法来知道varargs的类型。如果不知道类型,就无法获取它们的值。因此,您必须根据函数如何知道其参数是什么类型来编写代码 您要执行以下操作:
stringstream
中组装整个日志消息您需要最后一次检查,因为“foo bar 12.3.4.5 baz”和“foo 2.3.4.51 bar”一样包含“2.3.4.5”。因此,如果您找到字符串,并且它后面或前面有一个数字,您仍然希望记录消息。没有任何语法糖分可以做到这一点,因为没有通用的方法来了解varargs的类型。如果不知道类型,就无法获取它们的值。因此,您必须根据函数如何知道其参数是什么类型来编写代码 您要执行以下操作:
stringstream
中组装整个日志消息您需要最后一次检查,因为“foo bar 12.3.4.5 baz”和“foo 2.3.4.51 bar”一样包含“2.3.4.5”。因此,如果您找到字符串,并且后面或前面有一个数字,您仍然希望记录消息。不,没有。无论如何,你不应该在C++中使用VARARGS,而是使用可变模板。< /P> < P>不,没有。无论如何,你不应该在C++中使用VARARGS,而是使用可变模板, 嗯,不,没有变量访问列表的索引访问;只需逐项检查,因此您必须循环检查它们;这就是
vprintf
等的工作原理。当您遍历这些项时,您需要知道有多少项,通常是它们的类型,这是由约定确定的。对于vprintf
等,格式字符串中的项目数必须至少与格式说明符的数量相同,并且每个格式说明符都会告诉您参数的预期类型。您可以采用的另一个约定是使用sentinel值来标记参数列表的末尾;对于同构列表,如指针列表,空指针可以是一个可行的哨兵。嗯,不,没有对变量参数列表的索引访问;只需逐项检查,因此您必须循环检查它们;这就是vprintf
等的工作原理。当您遍历这些项时,您需要知道有多少项,通常是它们的类型,这是由约定确定的。对于vprintf
等,格式字符串中的项目数必须至少与格式说明符的数量相同,并且每个格式说明符都会告诉您参数的预期类型。您可以采用的另一个约定是使用sentinel值来标记参数列表的末尾;对于同类列表,如指针列表,空指针可能是一个可行的标识符。不,C++中没有什么可以做到这一点。在该示例中,还提供了所有参数都是双精度的。您需要参数的类型和长度,这在您的案例中是一个大问题。@DavidSchwartz您是对的。我的意思是,我甚至没有长度。不,没有什么可以在C++中这样做。你不正确的是,在课堂上,只对长度进行迭代。在该示例中,还提供了所有参数都是双精度的。您需要参数的类型和长度,这在您的案例中是一个大问题。@DavidSchwartz您是对的。我的意思是,我甚至没有长度。你必须解析格式字符串,这将是一件非常痛苦的事情,必须编码。您必须理解并正确处理函数允许使用的每个格式说明符,找出它们需要的参数类型(如果有),并在varargs中跳过该类型。你已经把自己画进了一个角落,应该重新考虑设计,或者采取“希望它足够好”的方法,并strstrstr
临时缓冲区的输出。正如你所说,格式和检查包含可能很昂贵,我的记录器需要满足严格的性能要求。你已经把自己画进了一个角落。备份并修复设计。我对您的设计了解不够,无法发表评论。你想解决的问题到底是什么?(但最有可能的解决方案是完全输出到stringstream,然后查看流中是否出现子字符串。)要实现简单的logger方法。因此,您可以这样称呼它:Log(“从ip%s到ip%s的流量”、“10.1.1.1”、“1.1.1.1”)和许多其他呼叫。在筛选器中,我想检查其中一个参数值是否为“10.1.1.1”,因此不要记录它。您必须解析格式字符串,这将是一件非常痛苦的事情,必须编写代码。您必须理解并正确处理函数允许使用的每个格式说明符,找出它们需要的参数类型(如果有),并在varargs中跳过该类型。你把自己涂成了int
void Logger::Log(const char *format, ...) {
lock_guard<mutex> guard(mtx_);
if (!file_) {
file_ = fopen("application.log", "w");
}
time_t current = time(0);
tm *ptm = localtime(¤t);
stringstream ss;
ss << "\n[" << ptm->tm_min << ":" << ptm->tm_sec << "]";
fprintf(file_, ss.str().data());
va_list argptr;
va_start(argptr, format);
vfprintf(file_, format, argptr);
va_end(argptr);
fflush(file_);
}
Log("trafic from ip %s to ip %s", "10.1.1.1","1.1.1.1")