2012年3月24日土曜日

C++ の std系の関数たちまとめ その1

C++を勉強してるけど、std系の関数が多い
全部暗記できるわけないけど、どういう関数があるかは覚えておきたいので、まとめておこうというエントリです。
その2 があるかどうかは分かりません。

コンパイラはFree Software Foundation の g++です。

※C++歴数時間なので、サンプルは動きますが、いけてないところもあるかもです。
オライリーのC++実践プログラミングを参考にしています。

このエントリの目次
1.std::cout - 標準出力
2.std::cin - 標準入力
3.std::string - シングルバイト文字列を扱う
4.std::wstring - ワイド文字列を扱う
5.std::strcpy - Cの文字列をコピーする
6.std::strncpy - 文字数を指定してCの文字列をコピーする
7.std::strcat - Cの文字列を連結する
8.std::strncat - 文字数を指定してCの文字列を連結する
9.std::strlen - Cの文字列長を取得する
10.std::strcmp - Cの文字列を比較する
11.最後に

1.std::cout - 標準出力
標準出力で表示する。
#include <iostream>

int main() {
    //出力。文字列は二重引用符(")で囲む。
    std::cout << "Hello " << "World" << '\n';
    return 0;
}
実行例。
$ ./hoge 
Hello World
std::cout を使用するにはとりあえず、iostream をインクルードすればよい(そうすれば下記の std::cin も使用できるようになる)。
<<」を使います。
<< を繋げて使うこともできます。
空白も出力に含められる。
標準出力で改行を表示するには「'\n'」か、「"\n"」。

2.std::cin - 標準入力
標準ストリームからデータを入力する。
#include <iostream>

int main() {
    int in; 
    std::cout << "Enter any integer: ";

    //データ取得
    std::cin >> in;
    std::cout << "You entered " << in << "\n";
    return 0;
}
実行例。
$ ./hoge 
Enter any integer: 1
You entered 1

上述の通り、std::cin を使用するには、iostream をインクルードすればよいです。
>>」で、標準入力からのデータを取得します。

下記のように、std::cin 一行で複数のデータを代入することができます。
#include <iostream>

int main() {
    int in1;
    int in2;
    int in3;
    std::cout << "Enter some integers : ";
    std::cin >> in1 >> in2 >> in3;
    std::cout << "You entered " << in1 << " and " << in2 << " and " << in3 << "\n";
    return 0;
}
半角スペース区切りで複数データを入力できます。
実行例。
$ ./hoge 
Enter some integers : 10 20 30
You entered 10 and 20 and 30

3.std::string - シングルバイト文字列を扱う
シングルバイト文字列を扱う型。
#include <iostream>

//下の行はなくても僕の環境では動作しました
#include 

int main() {
    std::string str = "This is a pen.";
    std::cout << str << '\n';    //文字列出力

    std::cout << str[0] << '\n'; //1文字目出力。よくない方法。
    std::cout << str.at(0) << '\n'; //1文字目出力。よい方法。

    std::cout << "length is " << str.length() << '\n'; //文字列長出力
    
    std::string twice = str + " " + str;  //文字列の連結
    std::cout << twice << '\n';    
    return 0;
}
実行例。
$ ./hoge 
This is a pen.
T
T
length is 14
This is a pen. This is a pen.
オライリーのC++実践プログラミングでは「#include <string>」が必要と書いてますが、僕の実行環境では不要でした。

文字列の例えば1文字目を取得するには、配列の形で「[0]」とアクセスします(ゼロベース)。
が、これはよろしくない方法で、配列の範囲外を指定するとどこかのアドレスの値を読みに行くので、どうなるか分かりません。
その代わりにメンバ関数「at」を使用すると、そういう場合に例外を投げてプログラムを終了します。

文字列の連結は「+」でできます。

4.std::wstring - ワイド文字列を扱う
ワイド文字列(いわゆるマルチバイト文字列)を扱う型。

下記のサンプルはコンパイルできませんでした…。
「エラー: ‘operator<<’ で ‘std::cout << str’ 内にあるものが適合しません」というエラーが出てしまいます。
標準出力の箇所でエラーが出てしまうんですが、どうやったら出力できるんだろう…。
#include <iostream>
#include <string>

int main() {
    std::wstring str = L"ワイド文字列";
    std::cout << str << '\n';    
    return 0;
}

5.std::strcpy - Cの文字列をコピーする
std::stringクラスではない、Cの文字列をコピーする。
#include <iostream>
//cstringにstrcpyの定義がされている
#include <cstring>

int main() {
    char name[10];

    //name = "windblue";    //この記述は不可
    std::strcpy(name, "windblue");

    std::cout << name << '\n';
    return 0;
}
実行例。
$ ./hoge 
windblue

ただし、コピー先の文字列の配列(上記の例だと「name」)のより、コピー元のデータ(上記の例だと「"windblue"」)の方が大きい場合、ランダムメモリを破壊してしまいます。
使わないほうが良さそうです。

安全にコピーするには下のstrncpyを使用します。

6.std::strncpy - 文字数を指定してCの文字列をコピーする
#include <iostream>
//cstringにstrncpyの定義がされている
#include <cstring>

int main() {
    char name[5];

    std::strncpy(name, "windblue", sizeof(name) - 1); 
    std::cout << name << '\n';
    return 0;
}
実行例。
$ ./hoge 
wind

Cの文字列の終端には「\0」という特殊な文字(NULという)が必要な仕様なので、 sizeof(name) - 1 と記述しています。
なので、上の例だと、nameの中身は最終的には{'w', 'i', 'n', 'd', '\0'}という風になっています。
(\0は自動で格納される)

7.std::strcat - Cの文字列を連結する
#include <iostream>
//cstringにstrcatの定義がされている
#include <cstring>

int main() {
    char name[10];

    std::strcpy(name, "wind");
    std::strcat(name, "blue");

    std::cout << name << '\n';
    return 0;
}
実行例。
$ ./hoge 
windblue

8.std::strncat - 文字数を指定してCの文字列を連結する
#include <iostream>
//cstringにstrncatの定義がされている
#include <cstring>

int main() {
    char name[7];

    std::strcpy(name, "wind");
    std::strncat(name, "blue", sizeof(name) - std::strlen(name) - 1); 
    name[sizeof(name) - 1] = '\0';

    std::cout << name << '\n';
    return 0;
}
実行例。
$ ./hoge 
windbl

strncat関数を使用した場合はNULを自動的に追加してくれないようなので、予めNUL文字の文字数分(1文字分)の余裕を持たせてコピーし、最後に手動でNULを追加しています。

9.std::strlen - Cの文字列長を取得する
#include <iostream>
//cstringにstrlenの定義がされている
#include <cstring>

int main() {
    char name[10];
    std::cout << std::strlen(name) << '\n';
    return 0;
}
実行例。
$ ./hoge 
10


10.std::strcmp - Cの文字列を比較する
#include <iostream>
//cstringにstrcmpの定義がされている
#include <cstring>

int main() {
    char str1[10];
    char str2[10];

    std::strcpy(str1, "hoge");
    std::strcpy(str2, "hoge");

    if (std::strcmp(str1, str2) == 0) {
        std::cout << "str1 == str2" << '\n';
    } else {
        std::cout << "str1 != str2" << '\n';
    }   

    return 0;
}
実行例。
$ ./hoge 
str1 == str2

strcmp(a, b); で、aがbよりも小さい場合は 負数、aがbよりも大きい場合は 正数 を返却する。

11.最後に
「\0」の扱いに慣れないので、難しいなあ。
慣れないというか、忘れただけですが…

間違いがあったらコメント頂けると助かります。

Related Posts Plugin for WordPress, Blogger...