2

このような構造があります。

struct Address {
    int id;
    int set;
    char name[MAX_DATA];
    char email[MAX_DATA];
};

そして、アドレスを設定する関数。

void Database_set(struct Connection *conn, int id, const char *name, const char *email) {
    struct Address *addr = &conn->db->rows[id];
    if(addr->set) die("Address already set");

    addr->set = 1;
    char *res = strncpy(addr->name, name, MAX_DATA);
    if(!res) die("Name copy failed");

    *res = strncpy(addr->email, email, MAX_DATA);
    if(!res) die("Email copy failed");
}

しかし、この行の後、addr->name の最初の文字が壊れます。

*res = strncpy(addr->email, email, MAX_DATA);

何か案は?

4

2 に答える 2

6

strncpy最初の引数を返すので、その後

char *res = strncpy(addr->name, name, MAX_DATA);

変数resaddr->name(同等に&(addr->name[0])) を保持するので、

*res = strncpy(addr->email, email, MAX_DATA);

実行されると同等です

addr->name[0] = strncpy(addr->email, email, MAX_DATA);

この割り当ては、 の最初の文字を破損するものですaddr->name。Greg Hewgill が言うように、 の戻り値を確認したり保存したりする必要はありませんstrncpy

于 2012-06-23T22:34:15.100 に答える
3

関数はここで必要なものではないと思いstrncpy()ます。次の呼び出しを検討してください。

strncpy(addr->name, name, MAX_DATA);

nameMAX_DATAまたはそれ以上の文字がある場合、これは からnameにバイトをコピーし、宛先を NUL で終了しaddr->nameません。次の 2 つの一般的な選択肢があります。

  1. 次のようなコードを使用して、結果を手動で NUL 終端します。

    addr->name[MAX_DATA-1] = '\0';
    

    ただし、これは毎回忘れずに行う必要があるため、エラーが発生しやすくなります。

  2. strlcpy()ソースが完全に収まらない場合でも、常に宛先を NUL で終了する (通常は BSD 派生システムで使用できますが、標準ではありません)などのライブラリ関数を使用します。

于 2012-06-23T22:33:45.417 に答える