1

基本的に、文字列をトークン化し、strncpy見つかった文字列を構造体のメンバー、つまり stringid に変換しています。もちろん、終端がないという問題に悩まされています。そのために余分な配列スペースを追加しましたが、適切に追加する方法がわかりません。

私はそれを次のようにしました:

my_struct[iteration].stringID[ID_SIZE-1] = '\0' //updated

それが本当に機能するかどうかはわかりませんが、IMO は恐ろしいものに見えます。

null 文字または 0 を Str(n)cpy すると、GCC と MinGW によって警告が生成されます。

warning: null argument where non-null required (arg 2)

これをきれいな方法で行う方法がわかりませんか?メンバー配列をすべてゼロに memset し、文字列をコピーして null 終端にうまく収まるようにすることを考えていました。何か提案や実践はありますか?

4

4 に答える 4

3

2つのこと:

  1. 非常に予期しないセマンティクスがあることに注意しstrncpy()てください。文字列で完全に満たされていない場合は常にバッファーを 0 で埋め、バッファーが完全に満たされている場合は文字列を終了しません。これらはどちらも奇妙で、使用しないことをお勧めします。
  2. stringID[ID_SIZE]やっているように、そのサイズで配列にインデックスを付けないでください。それは範囲外です。

最善の解決策は、あまり奇妙でない のカスタム バージョンを作成するstrncpy()か、(入力の長さがわかっている場合) を使用することstrcpy()です。

UPDATE : 入力トークンの長さが静的であるが、トークン化プロセスのためにソース バッファーで 0 で終了していない場合はmemcpy()、手動で終了するだけです。

const char * token = ...; /* Extract from tokenization somehow. Not 0-terminated. */
const size_t token_length = ... /* Perhaps from tokenization step. */
memcpy(my_struct[iteration].stringID, token, token_length);
my_struct[iteration].stringID[token_length] = '\0';

上記をマクロで「ラップ」する必要はないと思います。

于 2011-05-04T12:08:37.737 に答える
1

実際、あなたが提案した方法で null を終了することはまったく恐ろしいことではなく、個人的には非常に気に入っています。

私の意見では、同様の方法でマクロとして定義するのが最善の方法です。

// for char* blah;
#define TERMINATE_DYNAMIC_STRING(str, len) str[len] = '\0';
// for char mytext[] = "hello";
#define TERMINATE_STRING(str) str[sizeof(str)/sizeof(str[0]) - 1] = '\0';

その後、コード全体で必要なだけ使用できます。

Windows では、文字列をコピーするときにnullで終了する次の関数が Microsoft から提供されています。

于 2011-05-04T12:14:29.830 に答える
0

他の人が指摘したように、strncpy奇妙なセマンティクスがあります。境界のある文字列のコピーを行う慣用的な方法はstrncat、空の文字列にコピーすることです。

my_struct[iteration].stringID[0] = '\0';
strncat(my_struct[iteration].stringID, src, ID_SIZE-1);

これは常に終端の NUL を追加します (そして、NUL を含めて最大で ID_SIZE 文字を埋めます)。

于 2011-05-04T12:32:29.527 に答える
0

NULL 終了を強制する strncpyz(char* pszTo, char* pszTo, size_t lSize) 関数を作成してしまいました。これを入れるライブラリがある場合、これはかなりうまく機能します。それを使用するには、コードの変更も最小限で済みます。

誰かが間違ったマクロへのポインターを渡すので、私はマクロ アプローチには熱心ではありません。

于 2011-05-04T17:13:00.597 に答える