2

Cで整数を文字列に変換する小さなコードがあります。コードは、32 ビットと 64 ビットの両方のプラットフォームで動作する必要があります。

ループで引数を解析しているので、バッファを作成するには malloc が必要です

int tmp_integer = /*read as integer*/
char* tmp_string = malloc(20* sizeof(char)); /*enough room for the biggest integer*/
snprintf(tmp_string, 20,"%d",tmp_integer); /*can I avoid using 20 here*/
a[i - 1] = tmp_string; /*save the parsed argument for final usage*/

私の質問は次のとおりです。

もともとバッファオーバーランから保護したかったので、snprintfを使用するのは正しいことではないと考えましたが、整数のサイズがわかっているので役に立たないと思います。それでも、ここでのベストプラクティスは何かを知りたいです。

4

6 に答える 6

2

メモリを動的に割り当てる場合、log10 を使用して、文字列に必要な桁数を計算できます。

int tmp_integer = /*read as integer*/ 
int signpadding = 0;
if tmpinteger < 0 then signpadding = 1;
int digitcount = (integer)floor(log10(abs(value)))+ 1 + signpadding;
char* tmp_string = malloc(digitcount * sizeof(char)); 
snprintf(tmp_string, digitcount,"%d",tmp_integer);
于 2011-10-17T12:05:51.957 に答える
2

この場合、あなたは正しいです。番号が 64 ビットを超えないことがわかっており、20 桁を超えないことを意味することもわかっています。したがって、実際に使用する必要はありませんsnprintf

バグ: 最大の符号なし 64 ビット数は 18,446,744,073,709,551,615 で、20 桁です。ただし、各文字列には最後に'\0'( NUL) 文字があります (したがって、ヌル終了文字列の用語です)。したがって、配列には 20 バイトではなく21バイトを割り当てる必要があります。

于 2011-10-17T12:16:32.837 に答える
1

問題は、その魔法の「20」がどこから来たのかということです。これは魔法なので、コード内で繰り返される整数リテラルではなく、記号定数として表す必要があります。シンボリック定数を使用すると、コンパイラにエラー チェックを行わせるという利点もあります。

#define MAX_INTEGER_DIGITS (20)

int value = /* ... */
char* tmp_string = malloc(MAX_INTEGER_DIGITS);
snprintf(tmp_string, MAX_INTEGER_DIGITS, "%d", value);

sizeof (char)(完全に冗長で(imo)非常に雑然としているため、私がどのように物を落としたかにも注意してください。)

パフォーマンスの観点からは、おそらく文字列フォーマッタの保護されたバリアントを廃止することができますが、malloc()とにかくここで呼び出すので (安価ではない)、おそらくそれを削除することは大きなメリットではありません。

于 2011-10-17T12:06:33.053 に答える
0

一時バッファーで sprintf を実行し、(sprintf の戻り値を使用して) 適切なサイズを割り当ててから、その一時ファイルをバッファーにコピーできます。

int tmp_integer = /*read as integer*/
static char tmp_string[20];
int size = sprintf(tmp_string,"%d",tmp_integer); 
char *myValueString = malloc((size+1)*sizeof(char));
a[i - 1] = strcpy(myValueString,tmp_string); 
于 2011-10-17T12:06:27.353 に答える
0

これは、 sum1stolemynameコード スニペットに基づいて変換する別の (あまりきれいではないかもしれません) 方法です。

char *convert_int_to_string(int value)
{
    int digitcount;
    char * tmp_string;
    int increment = 2; // one for rounding, one for '\0' terminator
    if(value <0){
            increment += 1; // make room for sign 
    }
    if(0 == value){
            tmp_string = malloc(2* sizeof(char));
            sprintf(tmp_string, "%u", 0);
    }
    else{
            digitcount = (int)floor(log10((double)abs(value)))+ increment;
            tmp_string = malloc(digitcount * sizeof(char));
            sprintf(tmp_string, "%d", value);
    }
    return tmp_string;
}
于 2012-11-19T15:52:53.410 に答える