3

I'm building a string here based on 4 arguments and calling it with system(), but seems kinda messy the way i have done it. Is there a more correct way i should have done this and not use all those strcat and str1-4?

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int main(int argc, char *argv[])
{

    char str1[40] = "sed -n 's/.*\\(";
    char str2[] = "\\)\\(.*\\)\\(";
    char str3[] = "\\).*/\\2/p' ";
    char str4[] = " > ";

    if (argc != 5)
    {
        fprintf (stderr, "Usage %s <LogFile> <token1> <token2> <DumpFile>\n",
                argv[0]);
                exit(EXIT_FAILURE);
    }

    strcat(str1, argv[2]);
    strcat(str1, str2);
    strcat(str1, argv[3]);
    strcat(str1, str3);
    strcat(str1, argv[1]);
    strcat(str1, str4);
    strcat(str1, argv[4]);

    system(str1);

    return 0;
}
4

6 に答える 6

8

コードの問題の 1 つは、引数が 40 バイトに収まるかどうかをチェックしていないことです。

私はおそらく使用しますsnprintf

snprintf(str, LENGTH, "sed -n 's/.*\\(%s...", argv[2]...);
于 2012-01-30T19:48:56.183 に答える
3

これにより、繰り返されるの2次動作が節約されstrcat()ます。OTOH、あなたが呼ぶと、それはノイズで失われますsystem()

char str1[4096];
char str0[] = "sed -n 's/.*\\(";

sprintf(str1, "%s%s%s%s%s%s%s%s", str0, argv[2], str2, argv[3], str3, argv[1], str4, argv[4]);

snprintf()バッファオーバーフローが心配な場合に使用できます(そうする必要があります。40バイトでstr1は不十分です。のように、96を最後から外しましたchar str1[4096];)。戻り値をチェックして、書き込まれた文字数を確認できます。

于 2012-01-30T19:50:43.623 に答える
2

あなたの人生をよりシンプルにするsprintfが常にあります。sptrintf を使用する場合は、バッファーが結果に対して十分な大きさであることを確認してください。境界チェックを行う、より安全なバージョンのsnprintfもあります。

于 2012-01-30T19:48:20.137 に答える
2

唯一の問題は、バッファ オーバーフローが発生する可能性があることです (入力が長すぎる場合)。それを修正するには、( を使用して) 文字列の長さを確認し、必要strlenな文字列を格納するのに十分なメモリを割り当てます。

十分なメモリを割り当てたら、ループを使用するsprintfか、作業を任せることができます。

于 2012-01-30T19:48:29.377 に答える
2

str1長さはわずか 40 バイトであり、追加するデータが多すぎます。スタック オーバーフローが発生する可能性があります。私はするだろう:

char buffer[1000]; // Choose a reasonable size
snprintf(buffer, sizeof(buffer),
    "sed -n 's/.*\\(%s\\)\\(.*\\)\\(%s\\).*/\\2/p' %s > %s",
    argv[2], argv[3], argv[1], argv[4]);
于 2012-01-30T19:49:55.620 に答える
1

コードで任意の長さの引数を処理する場合は、を使用して文字バッファーを動的に割り当てる必要がありますmalloc

  1. ローカル変数を作成して必要な全長を計算し、繰り返し呼び出しを使用しstrlenてその長さを計算します。
  2. mallocnullターミネータにもう1文字追加することを忘れないでください。
  3. strcpyまたはstrcatを複数回使用して、文字列を作成します。
  4. を呼び出しsystemます。
  5. 電話freeをかけます(または、プロセスが終了しようとしている場合は気にしないでください)。
于 2012-01-30T19:50:50.800 に答える