2009-08-27 9 views
1

私は、インデックス値を文字列に変換するために関数を作成しています。これは、インデックスによって表される "フィールド"の詳細な記述です。gccは文字列リテラルフォーマット文字列を使用しないことについて警告しません

私は索引付けされたすべての冗長な記述を持つ素敵な配列を持っています。私は、問題は、私はそれをフォーマットするとき、文字列の中にいくつかの他の文字列を挿入する必要があるいくつかのケースのために来て、この

#define BUFFER_SIZE 40 
void format_verbose(uint32_t my_index, 
        char  my_buffer[BUFFER_SIZE]) 
    { 
    snprintf(mY_buffer, BUFFER_SIZE, "%s", MY_ARRAY[my_index].description); 
    } 

のようなコードを使用してバッファにそれをダンプする

。だから私が欲しいものは、このようなものです(この場合の説明には%sが含まれています)。

void format_verbose_with_data(uint32_t my_index, 
           char  my_buffer[BUFFER_SIZE]) 
    { 
    // ... 
    snprintf(mY_buffer, BUFFER_SIZE, MY_ARRAY[my_index].description, 
      some_string); 
    } 

私たちのmakeファイルは、(危険な)snprintf()警告を使用するように設定されており、警告はエラーとして扱われます。だから、それはコンパイルされません。私はちょっと危険ですが、文字列を制御して、それが呼び出されるすべての値で動作することを確認するために、この行の警告をオフにしたいと思います。

代わりに、私はこれにいくつかの他の方法を行いたいと思っていますが、それは特に私ドンのもののために、私の説明配列は醜いになりますので、私は本当に

void format_verbose_with_data(uint32_t my_index, 
           char  my_buffer[BUFFER_SIZE]) 
    { 
    // ... 
    snprintf(mY_buffer, BUFFER_SIZE, "%s%s%s" 
    MY_ARRAY[my_index].description1, some_string, 
    MY_ARRAY[my_index].description2); 
    } 

このソリューションを使用することに熱心ではありませんよ余分な値を追加する必要はありません。

答えて

0

思考の夜の後、私は手動で入力文字列を分割し、自分自身の%sマーカーを探し、その文字列separetleyを独自の%sでsnprintf()に送ります。この場合、書式文字列の型は1つしか許されませんが、これはあまり面倒ではありませんが、printf()スタイルのパーサーを完全に再実装しようとすると駄目になります。

void format_verbose_with_data(uint32_t my_index, 
           char  my_buffer[BUFFER_SIZE]) 
    { 
    char pre_description[BUFFER_SIZE]; 
    char post_description[BUFFER_SIZE]; 
    int32_t offset = -1; 

    offset = find_string(MY_ARRAY[my_index].description, "%s"); 
    ASSERT(offset >=0, "No split location!"); 
    // Use offset to copy the pre and post descriptions 
    // Exercise left to the reader :-) 
    snprintf(mY_buffer, BUFFER_SIZE, "%s%s%s" 
      pre_description, some_string, post_description); 
    } 
+0

文字列バッファーの長さをチェックする愚かな試みを取り除くために編集しました。もちろん、バッファがゼロ以外のすべての初期化されていない限り、動作しません。 – Peter

4

GCCには、行ごとに警告を表示しない機能がないため、運が悪いと思われます。とにかく、もしあなたのコーディング基準があなたが何かをしてはいけないと言えば、それらを倒す方法を探してはいけません。あなたが言う

もう一つのポイント、:

void format_verbose(uint32_t my_index, 
        char  my_buffer[BUFFER_SIZE]) 

あなたが本当にあなたの時間タイピングを無駄にしている - 言うことを明確にし、より多くの慣用句です:

void format_verbose(uint32_t my_index, 
        char  my_buffer[]) 

か:

void format_verbose(uint32_t my_index, 
        char  * my_buffer) 
+0

あなたの別の点は+1です:) –

+0

Cは渡されたバッファのサイズを何ら保護していないかもしれませんが、バッファサイズを残しておくほうがはっきりしているとは思いません。コードが正しいと仮定していることが明確に分かります。クラリティは見ている人の目には見えます:-) OTH、私はおそらく定義されたエラーの振る舞いか、アサーションのどちらかで短いバッファから身を守るべきでしょう。 コーディングの標準的な問題の1つは、型キャストです。コンパイラの警告を防ぐことができます。これにより、何が起こっているのかがより明確になります。 – Peter

0

あなたはsnprintf()で行うすべてが(ケースのようだとして)文字列をコピーしている場合、つまり、あなたが持っているすべては、あなたがおそらく、strcpy()を使用していない理由をフォーマット文字列などの1つまたは複数の"%s"、あります最初にstrlen()でソースの長さを確認しますか?

strncpy()であり、は、とよく似ていますが、そうではありません。ターゲットバッファには常に0が埋め込まれ、ソースがバッファサイズを超えた場合、は文字列をヌル終了しません。

+0

あなたの答えをありがとう!私は古くからこの仕事を断念していました:-(とにかく、私は2つの機能の間に大きな違いがあるとは思っていません。コピーしたり、印刷したりして、文字列の真ん中に何かを挿入したかったので、 snprintf()の解決方法が好きでした。 – Peter

関連する問題