 今回はvectorクラスを利用して、簡単な成績表を作ります。
今回はvectorクラスを利用して、簡単な成績表を作ります。
 起動すると、左のような簡単なメニューが表示されます。
データを入力する時は「1」を選択します。
起動すると、左のような簡単なメニューが表示されます。
データを入力する時は「1」を選択します。
 左の図のように氏名、得点の順に入力していきます。
左の図のように氏名、得点の順に入力していきます。
入力が終了したら「氏名」に「end」と入力します。
 入力が終了したらメニューから「2」を選択して、入力したデータを
表示して確認します。
入力が終了したらメニューから「2」を選択して、入力したデータを
表示して確認します。
[データ番号]氏名---得点
という形式で表示されます。氏名や得点を修正する場合は データ番号を指定します。
メニューの「3」を選択して得点を修正してみましょう。
 データ番号1番の佐藤さんの得点を80点に修正します。
データ番号1番の佐藤さんの得点を80点に修正します。
 確かに佐藤さんの得点が80点に修正されています。
確かに佐藤さんの得点が80点に修正されています。
では、プログラムを見てみましょう。
// vector03.cpp
#include <iostream>
#include <vector>
#include <string>
using namespace std;
int menu();
int input_data();
int show_data();
int shusei();
vector<int> point;
vector<string> shimei;
int main()
{
    int menuno, endmark = 0;
    string nm, yesno;
    while (1) {
        menuno = menu();
        switch (menuno) {
            case 1:
                input_data();
                break;
            case 2:
                show_data();
                break;
            case 3:
                shusei();
                break;
            case 0:
                endmark = 1;
                break;
        }
        if (endmark == 1)
            break;
    }
    return 0;
}
main関数の中は、無限ループになっています。
これを抜けることのできるのは、endmarkが1になった時のみです。
どういう時に1になるかというと、menunoが0になった時です。これは、
menu関数(自作、後出)が0を返した時(メニューで「終了」を選択した時)ですね。
int menu()
{
    int no;
    while (1) {
        cout << endl;
        cout << "**** MENU ***" << endl;
        cout << "1:データ入力" << endl;
        cout << "2:データ表示" << endl;
        cout << "3:データ修正" << endl;
        cout << "0:終了" << endl;
        cout << "---> ";
        cin >> no;
        if (no < 0 || no > 3) {
            cout << endl;
            cout << "番号が不正です" << endl;
            continue;
        }
        break;
    }
    return no;
}
メニューを表示する関数です。これも内部は無限ループになっています。 ユーザーが正しいメニュー番号(0-3)を入力するとループを抜けます。 戻り値はメニュー番号となりなります。
int input_data()
{
    string nm;
    int pt;
    while (1) {
        cout << "氏名 = ";
        cin >> nm;
        if (nm == "end")
            break;
        shimei.push_back(nm);
        cout << "得点 = ";
        cin >> pt;
        point.push_back(pt);
        cout << endl;
    }
    return (int)shimei.size();
}
データ入力の関数です。これも無限ループとなっています。氏名、得点が入力されるとpush_backメンバ関数でデータをvectorに 追加していきます。
氏名に「end」が入力されるとループを抜けて関数が終了します。
戻り値はvectorに格納されているデータの個数となります。(この値は このプログラムでは使用していません)
int show_data()
{
    int i, no;
    no = (int)point.size();
    cout << endl;
    for (i = 0; i < no; i++)
        cout << "[" << i << "]" << shimei[i] << "---" << point[i] << endl;
    return 0;
}
データを表示する関数です。データの個数だけfor文で、データ番号、氏名、得点を表示します。
int shusei()
{
    int no, datano, pt;
    string nm, yesno;
    vector<int>::iterator p;
    vector<string>::iterator q;
    p = point.begin();
    q = shimei.begin();
    datano = (int)point.size();
    while (1) {
        cout << endl;
        cout << "修正するデータの番号 = ";
        cin >> no;
        if (no < 0 || no >= datano) {
            cout << "番号が不正です" << endl;
            continue;
        }
        cout << "氏名 = ";
        cin >> nm;
        cout << "得点 = ";
        cin >> pt;
        q += no;
        p += no;
        *q = nm;
        *p = pt;
        cout << "続けますか(Y/N) -- ";
        cin >> yesno;
        if (yesno == "N")
            break;
    }
    return 0;
}
データを修正する関数です。これまた、無限ループとなっています。まず、修正するデータ番号を入力させます。データ番号は0からデータの個数−1 までとなります。この範囲外の入力があった場合はその旨表示して、continue文で ループの最初に戻ります。
データ番号が範囲内にあれば、氏名、得点を入力させます。
さて、データの修正には「反復子」と呼ばれるものを使うと便利です。
vector<型名>::iterator 名前;というような感じで宣言します。
vector<int>::iterator p;
p = point.begin();
というようにすると、pはpointオブジェクトの最初のデータを指しています。 データそのものは
*p
で表すことができます。これを参照したり、これに代入することも可能です。
p++;
とすると、pは次のデータを指すことになります。さらに、
p += N;
とすると、pは最初に指し示していたものより、N個後ろのデータを指すことになります。
同様に
p--;
とか
p -= N;
などとすることもできます。
実際にはデータが存在しないところを指し示してしまうと、結果はどうなるかわかりませんので注意してください。
ちょっとポインタと似ているところがありますね。
さて、このプログラムでデータを追加するにはメニューから再度「データ入力」を選択すれば可能です。しかし、データの削除ができません。これを改良してみてください。
Update Nov/05/2002 By Y.Kumei