あなたのコードは未定義のビヘイビアを呼び出し、何らかの出力を生成する理由を説明しようとします。あなたが<stdio.h>
、また<string.h>
を含まない
:
は、ここで問題となっています。以前定義されていない関数を呼び出すことはOKではありません。未定義の動作を避けるために、適切なヘッダーファイルをインクルードします。
char dest[0];
は、サイズが0
の配列を定義します。そのようなオブジェクトにアクセスすることはできません。そのアドレスは意味がありません。 gcc
とclang
はこれを許可しますが、C標準の拡張として許可します。この定義は誤字のように見えますが、このような愚かなバグを防ぐ有用な警告を有効にするには、gcc -Wall -W
またはclang -Weverything
を使用してください。
strncpy(dest, src, 4);
は、dest
の長さが4
より小さいため、未定義の動作を呼び出します。 strncpy
は、ソース文字列の長さがsize引数より大きいか等しい場合に宛先配列をNULL終了しないため、の長さを持つdest
の場合は、エラーが発生しやすくなります。ここで"santosh"
の長さは7
なので、dest
は、s
,a
,n
およびt
の文字を保持しますが、ヌルターミネータは使用できません。ループのwhile
は、while (dest[i])
がサイズを超えてdest
にアクセスするため、未定義の動作を呼び出します。 strncpy()
はエラーが発生しやすく、そのセマンティクスは広く誤解されており、非常に簡単にバグを引き起こします。 この機能を使用しないでください。
としてはdest
は、現在定義されるように逆参照することができないか、char dest[4];
と定義した場合であってもためwhile (dest[i])
は未定義の動作を起動し、上記説明しました。
はここsnprintf()
とstrncat()
を使用して、改良版である:
#include <stdio.h>
#include <string.h>
int main(void) {
char src[] = "santosh";
char dest[5];
*dest = '\0';
strncat(dest, src, 4);
printf("%s\n", dest); // will output "sant"
for (int i = 0; dest[i]; i++) {
printf("%c", dest[i]); // will output "sant" too
}
printf("\n");
snprintf(dest, sizeof dest, "%s", src);
printf("%s\n", dest); // will output "sant"
for (int i = 0; dest[i]; i++) {
printf("%c", dest[i]); // will output "sant" again
}
printf("\n");
for (int i = 0; src[i]; i++) {
printf("%c", src[i]); // will output "santosh"
}
printf("\n");
return 0;
}
'char型のDEST [0]' < - かなり多くのあなたの全体のプログラムは、この時点では未定義の動作です。その宣言で言っていることは、 'dest'配列が0文字の* fixed *サイズであるということです。したがって、何も格納することはできず、そのアクセス(read *または* write)は未定義です。 –
イギリスのポップバンド** UB40 **にちなんで名付けられました。あなたはまた 'C++'タグを削除することを検討するべきです。 –
これは未定義の動作です。 Cはあなたが望む場所に書くことを可能にします。そして、もしあなたがそうしなければならないかどうかを決めるのはあなた次第です... – Charles