0

ポインタの配列を持つ構造体があります。「1」、「2」などの文字列形式で配列の数字を挿入したいと思います。

ただし、sprintfとstrncpyのどちらを使用するかに違いはありますか?

私のコードに大きな間違いはありますか?私は無料で電話しなければならないことを知っています、私は私のコードの別の部分でそれをします。

アドバイスありがとうございます!

struct port_t
{
    char *collect_digits[100];

}ports[20];

/** store all the string digits in the array for the port number specified */
static void g_store_digit(char *digit, unsigned int port)
{
    static int marker = 0;
    /* allocate memory */
    ports[port].collect_digits[marker] = (char*) malloc(sizeof(digit)); /* sizeof includes 0 terminator */
    // sprintf(ports[port].collect_digits[marker++], "%s", digit);
    strncpy(ports[port].collect_digits[marker++], digit, sizeof(ports[port].collect_digits[marker]));
}
4

5 に答える 5

3

はい、あなたのコードにはいくつかの問題があります。

  • C では、 の戻り値をキャストしないでくださいmalloc()。これは不要で、エラーを隠すことができます。
  • 格納するサイズではなく、ポインターのサイズに基づいてスペースを割り当てています。
  • コピペも同様。
  • staticmarkerが何をするのか、またその周りのロジックが本当に正しいのかは不明です。変更されるスロットですかport、それとも静的変数によって制御されますか?

配列のスロットごとに 1 桁のみを格納しますか?それとも複数桁の数字を格納しますか?

宣言が与えられた場合、その関数は次のようになります。

/* Initialize the given port position to hold the given number, as a decimal string. */
static void g_store_digit(struct port_t *ports, unsigned int port, unsigned int number)
{
  char tmp[32];

  snprintf(tmp, sizeof tmp, "%u", number);
  ports[port].collect_digits = strdup(tmp);
}
于 2009-03-31T06:34:31.997 に答える
2
strncpy(ports[port].collect_digits[marker++], digit, sizeof(ports[port].collect_digits[marker]));

これは正しくありません。

collect_digits に一定量のメモリを割り当てました。

char *digits をそのメモリにコピーします。

コピーする長さは strlen(桁) です。実際にコピーしているのは sizeof(ports[port].collect_digits[marker]) で、これにより単一の char * の長さが得られます。

sizeof() を使用して、割り当てられたメモリの長さを確認することはできません。さらに、数字が割り当てたメモリと同じ長さであることを先験的に知っていない限り、 sizeof() が割り当てられたメモリの長さを教えてくれたとしても、間違ったバイト数をコピーすることになります (多すぎます。桁の長さをコピーする必要があります)。

また、2 つの長さが常に同じであっても、この方法で長さを取得することは表現力がありません。読者を誤解させます。

指定されたコピーの長さがソース文字列の長さよりも大きい場合、strncpy() は末尾の NULL でパディングすることにも注意してください。そのため、数字割り当てられたメモリの長さである場合、終端のない文字列になります。

sprintf() 行は機能的に正しいですが、あなたがしていることについては、(strncpy() とは対照的に) strcpy() は、私がコードを見て知っていることから、正しい選択です。

何をしようとしているのかはわかりませんが、コードは非常にぎこちなく感じます。

于 2009-03-31T06:38:47.247 に答える
1

最初に、なぜポインタの配列があるのでしょうか? ポート オブジェクトに複数の文字列が必要ですか? おそらくプレーンな配列またはポインターのみが必要です (malloc後で -ing を実行するため)。

struct port_t
{
    char *collect_digits;
}ports[20];

文字列のアドレスを渡す必要があります。そうしないと、malloc がローカル コピーに対して機能し、支払った金額が返されません。

static void g_store_digit(char **digit, unsigned int port);

最後に、 はsizeofポインター コンテキストに適用され、正しいサイズが得られません。

于 2009-03-31T06:33:00.130 に答える
1

malloc()andを使用する代わりに、使用strncpy()するだけstrdup()です。コンテンツを保持するのに十分なバッファ ビンを割り当て、コンテンツを新しい文字列にコピーします。すべて一度に行います。

したがって、まったく必要ありませんg_store_digit()- を使用して、呼び出し元のレベルstrdup()で維持するだけです。marker

于 2009-03-31T06:38:46.607 に答える
1

元のコードの別の問題: ステートメント

strncpy(ports[port].collect_digits[marker++], digit, sizeof(ports[port].collect_digits[marker]));

markermarker++同じ式で参照します。この場合、++ の評価順序は定義されていません。2 番目の参照markerは、インクリメントが実行される前または後に評価されます。

于 2009-03-31T14:42:09.017 に答える