28

特に文字列操作関数を使用しながら、strcpyこの小さなプログラムを実行しました。

char s1[8]="Hellopo";
char s2[4]="sup";
strcpy(s1,s2);
cout<<s1<<endl;

s1を印刷したとき実際には「sup」を印刷しただけです。「suplopo」を印刷することを期待していました。

それから私はこれをしました:

cout<<s1+4 << endl;

「opo」を印刷しました。

そしてこれの出力:cout<<s1+3<<endl; 何もありませんでした

それで、それについて少し考えた後。

私はこの結論に達しました。C ++は、nullターミネータに達すると、文字列の出力を停止するためです。したがって、nullはstrcpy関数にコピーされている必要があります。結果は次のようになります。

s --u --p-\ 0 --o --p --o-\ 0;

これが正しいかどうか教えてください。そして、私がそうでない場合は、私を訂正してください。

そして、あなたが提供するためにもっと情報を持っているならば、してください。

4

7 に答える 7

46

あなたの推論は正しく、まともなマニュアルで簡単に確認できたでしょう:

このstrcpy()関数はsrc、終了ヌルバイト('\0')を含む、が指す文字列を、が指すバッファにコピーしますdest

于 2012-08-06T15:13:58.450 に答える
5

終了文字のコピーに関するあなたの推論は正しいです。C ++標準(言語の最も信頼のおける仕様)は、この問題に関してCに準拠しています(たとえば、C ++ 14はC99に準拠し、C ++ 17はC11に準拠しています)。

C11標準には、次のように書かれていstrcpyます。

7.24.2.3strcpy機能

あらすじ:

#include <string.h>
char *strcpy(char * restrict s1, const char * restrict s2);

説明:

この関数は、が指す文字列(終了ヌル文字を含む)を、が指す配列にstrcpyコピーします。オーバーラップするオブジェクト間でコピーが行われる場合、動作は定義されていません。s2s1

戻り値:

このstrcpy関数はの値を返しますs1

文字列の最初の3文字を置き換えたいだけの場合はmemcpy()、特定のバイト数をコピーするために使用できます。

memcpy(s1, s2, strlen(s2));

これはそれらのバイトをコピーするだけで、それ以上はコピーしないことに注意してください。s1が少なくともの長さの文字列でない場合はs2、うまく終了する可能性は低いです:-)


そして、コメント「...この文字列になります:」について1つ覚えておいてくださいsup\0opo\0

それは文字列ではありません。Cの文字列(およびC ++のレガシー文字列)は、最初の \0ターミネータまでの一連の文字として定義されます。

元の文字(現在は2番目)までの一連の文字があるかもしれません\0が、文字列は実際にはそれよりも短くなっています。これは少し衒学的に思えるかもしれませんが、定義を理解することが重要です。

于 2018-02-01T02:08:32.743 に答える
2

あなたは正しいです。最初に期待した効果には、を使用しますstrncopystrncopyコピーされる文字列の正しい長さを指定する限り、ヌルターミネータをコピーします。

于 2012-08-06T15:15:29.313 に答える
1

のマニュアルページからstrcpy

このstrcpy()関数はsrc、終了ヌルバイト('\0')を含む、が指す文字列を、が指すバッファにコピーしますdest。文字列は重複してはならず、宛先文字列 destはコピーを受信するのに十分な大きさである必要があります。

于 2012-08-06T15:15:07.533 に答える
1

正解です。

http://pubs.opengroup.org/onlinepubs/009695399/functions/strcpy.html

strcpy()関数は、s2が指す文字列 (終了ヌルバイトを含む)をs1が指す配列にコピーします。

于 2012-08-06T15:15:35.160 に答える
1

はい、これは正しいです。strcpyにはヌルターミネータが含まれます。文字列を新しいメモリブロックにコピーするかのように、デフォルトでnullで終了させることが重要です。この場合、strncpyがあなたが求めているものかもしれないと私は信じています。

また、コードのテストのみであったことも知っていますが、文字列で+ Xオフセットを使用する時代には注意が必要です...asciiは通常、現在住んでいるutf8/unicodeの世界でリアエンドの人々を噛みます。

于 2012-08-06T15:17:41.387 に答える
0

はい、あなたはあなたの推論が正しいです、そしてあなたが明示的に4番目の文字's1[3]'を次のように整数として型キャストしたとしたら:

cout <<(int)s1 [3];

NULL文字のASCII値である出力として「0」を取得しているはずです。

于 2019-07-08T10:51:04.197 に答える