C言語のstring.hにはstrncpy関数が定義されていますが、この関数を用いるときは注意しなければならない点があります。それは、コピー先には終端記号「\0」が自動的につかないこと。第3引数で指定した範囲しかコピーしないので、自分自身で終端記号を付ける必要があります。
たとえば、こんなコードがあったとしましょう。
char* str = (char*)malloc(sizeof(char)*100); strncpy(str,"abcde",3);
すると、変数strが指す記憶領域には次のように記録されます。
str → | a | b | c | x | …| \0 | …|
上で書かれているxはランダムな文字(値)です。そのため、運よくxに終端記号が入る場合もありますが、別の値が入る場合もあります。そうなった場合はその文字(値)自身も文字列の一部として認識されてしまいます。このような場合を防ぐには、自分自身で終端記号を代入するのが一番確実です。
*(str+3) = '\0';
上のコードではマジックナンバーで指定してありますが、実際は変数か定数で指定したほうがよいでしょう。
Comments [2]
hszakiさん
strncpyの挙動は,ぜんぜんおかしくないです.'\0'入れない方が,汎用性高いんですよ.
例えば,
str = "aaabbbccc";
の,bbbの部分をBBBに変えたい時,'\0'が入らないなら,
strncpy(str+3, "BBB", 3);
とできるけど,'\0'が入ってしまう仕様では,strncpyを使用できない.
tetsuさん
確かにその通りなんですけどね?。
こういうところをちょっと忘れてしまうと、かなり致命的なバグになり得るんで、もうちょっとなんとかならないかな?とは思いますね。
そんな訳で、個人的にはsprintfの方をよく使ったりしますね。hszakiさんが示した例ではもちろんstrncpyを使うと思いますけどね。
コメントする