9
13

More than 5 years have passed since last update.

string.h は忘れよう

Last updated at Posted at 2015-10-19

 C++での開発が当たり前になって久しい。文字コードもunicodeサポートが当然になっている。バッファオーバーフローへの対策が必須の時代になっている。もうstring.hを使うのはやめよう。

#include <string>
int main(int argc, char* argv[]){
    std::string message = "Hello World";
    std::cout << message << std::endl;
}

としようじゃないか。

string.hは、ASCIIコードの時代、バッファーオーバーフローの問題も今ほど大きくない時代にできた。今となっては、OSや基本のライブラリを作るようなプロフェッショナル(=いわばレーサー)が使うようなライブラリだと思う。

#include <string>

「std::string を使うことで、オーバーヘッドが大きくなる。」と気にしなければならないほど、他の部分をバリバリにチューニングをしてあるプログラムを書いている人はどれほどいるだろう。私の書いているプログラムの中では、それ以外の要因の方が圧倒的に遅くしている要因です。string.hのライブラリを使うとchar*でポインタを使うことになります。
 ファイルシステムの文字コードにUTF8が使われているときに、char* を使うとどうなるのか、私は理解していません。UTF8の文字コードの中で、文字列の検索や置換をしたときに何が起きるのかも理解しておりません。
 でも、実際のプログラムの中では、文字列の検索や置換を行っています。だから、私はstring.hの関数は忘れることにしました。自分のプログラムの中には、他にも危なっかしいところが山ほど山ほどあります。#include <string>の関数は、文字コードの問題や、バッファーオーバーフローへの対策などを考えた時代以降に開発されてきたものです。UTF8がうまく実装されていることは、様々なプログラムの中でたくさんの国・地域の処理できていることからわかります。
 std::string を使いましょう。char*のインターフェースが必要なときは、.c_str()メソッドを使えば十分です。
 std::string を使って安全運転でC++のプログラムを楽しく開発しましょう。

付記:
 文字列の長さが固定長であって文字列の連結をするとオーバーフローする心配をしなければならない枠組みよりは、文字列の長さは連結しただけ長くなる枠組みでは、後者の方がメモリが潤沢な環境ではコーディングする側には考えやすいと思っているのです。
 文字コードの問題には深入りしたくないのです。
strcpy()の代わりに、strcpy_s()を用いても、目的の文字列操作にはならないことを次のwebページの記事は書いています。
strcpy_sなんて使うな

char pathname[1024];
などと、たいがいの場合に足りそうな文字列の長さを確保しても、メモリの効果的な利用にはなっていません。メモリの使用量の上限(あるいは固定値)を設定することで、リソースを明確にするという意味は持っていますが、std::stringを用いた方が、通常のたちのよい場合には、メモリの使用量が少なくできるではないかと思います。

付記:多バイトコードの扱い
wcscpy 関数と _mbscpy関数がVisual C++ にはある。C++プログラムを特定のコンパイラだけでしかコンパイルできないようにはしたくない。
一番単純な使い方で破綻が生じない限り、単純なやりかたをしたいと思っている。それがstd::string を使おうと考えている理由です。

SHIFT_JIS2バイト目が5C等になりうることによる問題

付記:
 ファイルの操作にはBoostを使おう。

9
13
4

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
9
13