Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/133.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ c++;检查varargs是否包含_C++ - Fatal编程技术网

C++ c++;检查varargs是否包含

C++ c++;检查varargs是否包含,c++,C++,是否有一个简单的api(没有循环)来检查varargs是否包含一些值(char*) 如果没有简单的API,如何在没有任何参数计数的情况下进行迭代 我的方法应该能够根据配置IP过滤日志,因此我需要检查其中一个参数是否为10.3.2.2(某些配置IP) 还有很多其他的电话。在过滤器中,我想检查其中一个参数值是否为“10.1.1.1”(例如),所以不要记录它。没有任何语法糖分可以这样做,因为没有通用的方法来知道varargs的类型。如果不知道类型,就无法获取它们的值。因此,您必须根据函数如何知道其参数

是否有一个简单的api(没有循环)来检查varargs是否包含一些值(char*)

如果没有简单的API,如何在没有任何参数计数的情况下进行迭代

我的方法应该能够根据配置IP过滤日志,因此我需要检查其中一个参数是否为10.3.2.2(某些配置IP)


还有很多其他的电话。在过滤器中,我想检查其中一个参数值是否为“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(&current);
        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")