-1

引数を取る値を保存する関数があります。入力を受け入れるには、 として、char*次に を介して という 2 つの方法を実装する必要がありますstrncpy

すなわち: a . Add("123456/7890", "John", "Doe", "2000-01-01", "Main street", "Seattle");

strncpy を使用するまでは問題なく動作します。

bool status;
char lID[12], lDate[12], lName[50], lSurname[50], lStreet[50], lCity[50];  

strncpy(lID, "123456/7890", sizeof ( lID));
strncpy(lName, "John", sizeof ( lName));
strncpy(lSurname, "Doe", sizeof ( lSurname));
strncpy(lDate, "2000-01-01", sizeof ( lDate));
strncpy(lStreet, "Main street", sizeof ( lStreet));
strncpy(lCity, "Seattle", sizeof ( lCity));
status = c . Add(lID, lName, lSurname, lDate, lStreet, lCity);
//is true 

strncpy(lID, "987654/3210", sizeof ( lID));
strncpy(lName, "Freddy", sizeof ( lName));
strncpy(lSurname, "Kruger", sizeof ( lSurname));
strncpy(lDate, "2001-02-03", sizeof ( lDate));
strncpy(lStreet, "Elm street", sizeof ( lStreet));
strncpy(lCity, "Sacramento", sizeof ( lCity));
// notice, that I don't even save it at this point

strncpy(lID, "123456/7890", sizeof ( lID));
strncpy(lDate, "2002-12-05", sizeof ( lDate));
strncpy(lStreet, "Sunset boulevard", sizeof ( lStreet));
strncpy(lCity, "Los Angeles", sizeof ( lCity));
status = c . Resettle(lID, lDate, lStreet, lCity);

status = c . Print(cout, "123456/7890");
//is true

この時点で、ID 123456/7890 の値を出力したいので、Name:John、Surname:Doe などです。それでも、最後の値として保存された値が出力されます。

123456/7890 Freddy Kruger
2002-12-05 Sunset boulevard Los Angeles
2002-12-05 Sunset boulevard Los Angeles

MyAddは次のように宣言されます。

  bool Add(const char * id,
        const char * name,
        const char * surname,
        const char * date,
        const char * street,
        const char * city);

Resettle関数は と同様に遅れますがAdd、名前と姓の引数を取らないだけです。すべての値はchar **配列に保存されます。

両方の入力を適切に受け入れることができるように、この状況を処理する方法を教えてください。

Ps:char*入力については、プログラム全体が問題なく動作するので、バグはないと思います..したがって、私は char* などを使用します...

4

3 に答える 3

3

ここで sizeof を使用するべきではないと思います。strncpy には文字列の長さが必要です (宛先文字列からソース文字列にコピーされる文字数)。

sizeof はポインタのサイズです (例: sizrof(IID) = アドレス サイズ、私のシステムでは 4)。

strlen() が必要だと思います。また、これは、宛先ポインターではなく、ソース ポインターで呼び出す必要があります。

strncpy(lID, "987654/3210", strlen ("987654/3210"));

IID が文字列をコピーするのに十分な長さであることを確認してください。そうしないと、バッファ オーバーフローが問題になる可能性があります

read char * strncpy ( char * destination, const char * source, size_t num ); 、 と

文字列から文字をコピー ソースの最初の num 文字をコピー先にコピーします。num 文字がコピーされる前にソース C 文字列 (null 文字によって通知される) の末尾が見つかった場合、合計 num 文字が書き込まれるまで、destination にゼロが埋め込まれます。

@JonathanLeffler に感謝: ( strlen() は、データが null で終了しないことを意味します。それは悪いことです。少なくとも strlen() + 1 バイトをコピーして、null ターミネータを取得してください)

注: source が num よりも長い場合、destination の最後に null 文字は暗黙的に追加されません (したがって、この場合、destination は null で終了する C 文字列ではない可能性があります)。

以下についてもお読みください: size_t strlen ( const char * str );

于 2013-04-13T04:55:43.913 に答える
2

問題はstrncpy()操作にありません。それはあなたが私たちに示していない資料にあります:

c.Add()
c.Resettle()
c.Print()

それらの 1 つまたは複数に問題がありますが、まだ確認できないため、デバッグのお手伝いはできません。


のデモンストレーションstrncpy()

voodoogiantanswerstrncpy()へのコメントには、 の動作に関する議論があります。次のデモンストレーションがあります。

strncpy(target, "string", strlen("string"));

出力を null で終了しません。

#include <string.h>
#include <stdio.h>

int main(void)
{
    char buffer[32];

    memset(buffer, 'X', sizeof(buffer));
    printf("Before: %.*s\n", (int)sizeof(buffer), buffer);
    strncpy(buffer, "123456/7890", strlen("123456/7890"));
    printf("After:  %.*s\n", (int)sizeof(buffer), buffer);
    return(0);
}

出力:

Before: XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
After:  123456/7890XXXXXXXXXXXXXXXXXXXXX

(はい、memset()バッファを null で終了しないことは十分承知しています。この例では、印刷が慎重に行われるため、その必要はありません。)

于 2013-04-13T05:07:00.013 に答える
0

lIDet alのデータ型がわからないため。したがって、sizeofコメントするのは難しいです。stringSTLのコンテナを使用しない理由に加えて

于 2013-04-13T05:00:11.287 に答える