0

varargs に何らかの値 (char*) が含まれているかどうかを確認するための単純な API (ループなし) はありますか?

単純な API がない場合、引数をカウントせずにどのように反復する必要がありますか?

私の方法では、構成 IP でログベースをフィルタリングできるはずなので、引数の 1 つが 10.3.2.2 (構成 IP) であるかどうかを確認する必要があります。

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")

と他の多くの呼び出し。フィルターで、パラメーター値の1つが「10.1.1.1」(たとえば)であるかどうかを確認したいので、ログに記録しないでください。

4

3 に答える 3

3

いいえ、ありません。とにかく、C++ では可変引数を使用しないでください。代わりに可変引数テンプレートを使用してください。

于 2012-08-25T14:34:48.557 に答える
2

varargs の型を知る普遍的な方法がないため、これを行うための構文糖衣はありません。タイプを知らなければ、その値を取得することはできません。したがって、関数が引数の型をどのように認識しているかに基づいて、これを行うコードを作成する必要があります。

あなたはこれをしたい:

  1. にログ メッセージ全体をまとめますstringstream

  2. 目的の文字列については、ログ メッセージを確認してください。

  3. そこに文字列が見つかった場合は、その前後に数字がないことを確認してください。

  4. 文字列が見つかり、その前後に数字がない場合は、ログに記録します。

「foo bar 12.3.4.5 baz」には「foo 2.3.4.51 bar」と同様に「2.3.4.5」が含まれているため、最後のチェックが必要です。そのため、文字列が見つかり、その後ろまたは前に数字がある場合でも、メッセージをログに記録する必要があります。

于 2012-08-25T14:34:41.740 に答える
-1

いいえ、変数引数リストへのインデックス付きアクセスはありません。アイテムごとに、それらをループする必要があります。それがどのようvprintfに機能するかです。アイテムを反復処理するときは、アイテムの数と、通常はそれらのタイプを知る必要があり、それは慣習によって確立されています。などの場合vprintf、少なくとも書式文字列内の書式指定子と同じ数の項目が必要であり、各書式指定子は引数の予想される型を示します。採用できるもう 1 つの規則は、番兵値を使用して引数リストの終わりをマークすることです。ポインターのリストなどの同種のリストの場合、null ポインターは実行可能なセンチネルになる可能性があります。

于 2012-08-25T14:56:54.000 に答える