C++サンプル集

【第1部】C言語(K&R検証)編

0027.数値を配列に入れる

ソース紹介

 このサンプルは、例えば、数字が並んでいるであろうファイル(あるいはコンソール入力)から、数値に変換して配列に入れるものです。いろんな応用がきくサンプルと思います。
 なおこのサンプルには0025.逆ポーランド電卓を実装するで紹介した、getch()およびungetch()関数が出てきます。
CPPファイルに記述
#include<iostream>
#include<cstdio>
#include<cctype>
using namespace std;


#define BUFSIZE 100
#define MAXOP 100
#define SIZE 10

char buf[BUFSIZE];
int bufp = 0;

int getch() {
    return (bufp > 0) ? buf[--bufp] : cin.get();
}
void ungetch(int c) {
    if (bufp >= BUFSIZE) {
        cout << "ungetch: これ以上追加できません" << endl;
    }
    else {
        buf[bufp++] = c;
    }
}


int getint(int* pn) {
    int c, sign;
    while (isspace(c = getch()))
        ;
    if (!isdigit(c) && c != EOF && c != '+' && c != '-') {
        ungetch(c);
        return 0;
    }
    sign = (c == '-') ? -1 : 1;
    if (c == '+' || c == '-') {
        c = getch();
    }
    for (*pn = 0; isdigit(c); c = getch()) {
        *pn = 10 * *pn + (c - '0');
    }
    *pn *= sign;
    if (c != EOF) {
        ungetch(c);
    }
    return c;
}

int main()
{
    int array[SIZE]{};
    for (int n = 0; n < SIZE && getint(&array[n]) != EOF; n++)
        ;
    for (auto v : array) {
        cout << v << endl;
    }

}
出力
123
456
789
852
147
963
^Z
123
456
789
852
147
963
0
0
0
0

サンプル説明

 ここで入力するのは^Zの手前までです。6つの数字が入力されます。それをint型の配列にいれて、EOFが入った段階で、その配列の中身を出力しています。10個の配列ですが、6つしか設定されないので、7個以降は 0 に表示されます。
 このサンプルの応用とすれば、例えば数字が並んだCSVファイルの読み込みに使えます。デリミタとして使うであろう , の扱いを考えなければいけませんがこのサンプルを少しいじっただけで実装できると思います。ぜひトライしてみてください。
 あと、これは蛇足なのですが、ポインタの表記に、僕はgetint(int* pn)の様にint側に寄せています。
 しかしK&Rではgetint(int *pn)pn側に寄せています。
 これは好みにもよるのですが、C言語派はgetint(int *pn)C++派はgetint(int* pn)とする傾向にあるようです。これはC++を作ったストラウストラップ氏がそうしているからなのですが、たとえばint *p;という宣言はpはint型のポインタという感じがします。一方int* p;int型のポインタpという感じがします。僕は後者の方がしっくりくるのでそうしています。

K&Rでの記述

 元になったのは第5章:ポインタと配列に記述されています。ポインタと関数引数の説明のところです。