1

snprintfin a loop では動作しませんlinuxが、 では正常に動作しwindowsます。

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

    int main( int argc, char **argv) {
      char buffer[255] ={0};
      for ( int i = 0; i < 10; i++) {
        snprintf(buffer, 255, "%s:%x\0",buffer,  i );
      }
      printf ( "BUFFER  = %s\n", buffer );
      return 0;
    }

このコードは既存のものを追加せずbuffer、最後の反復値のみを取ります。

4

5 に答える 5

5

次のように、バッファをターゲット文字列と引数の両方として使用するという未定義の動作を回避できます。

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

int main( int argc, char **argv) {
  char buffer[255] ={0};
  int offset = 0;
  for ( int i = 0; i < 10; i++) {
    offset += snprintf(buffer + offset, 255 - offset, ":%x\0", i);
  }
  printf ( "BUFFER  = %s\n", buffer );
  return 0;
}
于 2012-07-30T09:30:35.343 に答える
3

sprintf()結果配列をそれ自体に ' することは、未定義の動作です。

編集: 動作するコードが必要な場合は、次のようになります: 使用しますstrcat()(または、より安全な strncat などを使用して、バッファ オーバーフローに関する通常のセキュリティの議論をここに挿入します):

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

int main( int argc, char **argv) {
    char buffer[255] = { 0 };
    char fmtbuf[64];

    int i;
    for (i = 0; i < 10; i++) {
        snprintf(fmtbuf, 64, "%x", fmtbuf, i);
        strcat(buffer, fmtbuf);
    }

    printf ("BUFFER  = %s\n", buffer);
    return 0;
}

また、printf() 呼び出しでは、末尾のゼロを手動で書き出す必要はありません。自動的に追加されます。

于 2012-07-30T09:28:23.690 に答える
1

snprintfは Linux で指定どおりに機能しますが、コードはそれを追加しません。リンクされたドキュメントのを読んでください。

引数として (フォーマット文字列の後に) 宛先を使用しないでください。

追加したい場合は、固定バッファーがオーバーフローしないようにするか、バッファーが小さくなりすぎたときにそのバッファーを再割り当てしてください。

于 2012-07-30T09:26:30.233 に答える
0

'snprintf'で'buffer'をそれ自体に書き込むことはできませんでした。

テストコードは次のとおりです。

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

int main( int argc, char **argv) {
    char buffer[255] ={0};
    for ( int i = 0; i < 10; i++) {
        char tmp[255] = {0};
        strcpy(tmp, buffer);
        snprintf(buffer, 255, "%s:%x\0",tmp,  i );
        printf ( "BUFFER  = %s\n", buffer );
        }
    printf ( "BUFFER  = %s\n", buffer );  
    return 0;
}
于 2012-07-30T09:37:34.440 に答える
0

標準では、このコードは機能しないと明確に述べられています。まず、最初のバッファ引数が宣言されrestrictています。これは、別の引数にエイリアスを設定できないことを意味します。第二に、標準には強調のために次の条項があります。

7.19.6.5 snprintf 関数

説明

2 - [...] 重複するオブジェクト間でコピーが行われる場合、動作は未定義です。

于 2012-07-30T09:50:24.473 に答える