【第1部】C言語(K&R検証)編
0008.最も長い入力行を出力する
ソース紹介
CPPファイルに記述
#include <iostream>
#include <cstdio>
using namespace std;
#define MAXLINE 1000
//sに行を入れ、長さを返す
int getline(char s[], int lim) {
char c;
int i = 0;
while (--lim > 0 && (c = cin.get()) != EOF && c != '\n') {
s[i++] = c;
}
if (c == '\n') {
s[i++] = c;
}
s[i] = '\0';
return i;
}
// from を toにコピー
void copy(char to[], char from[]) {
for (int i = 0; (to[i] = from[i]) != '\0'; ++i) {
;
}
}
/*
最も長い入力行を出力する
*/
int main()
{
int len, max = 0;
char line[MAXLINE];
char longest[MAXLINE];
while ((len = getline(line, MAXLINE)) > 0) {
if (len > max) {
max = len;
copy(longest, line);
}
}
if (max > 0) {
cout << max << "文字" << endl;
cout << longest << endl;
}
else {
cout << "入力がありません" << endl;
}
return 0;
}
出力
abcdefghijklmnopqrstuvwxyz
0123456789
AAAAAAAAAAAAAAAA
Hello!Hello!Hello!Hello!Hello!Hello!Hello!
XXXXXXX
^Z
42文字
Hello!Hello!Hello!Hello!Hello!Hello!Hello!
サンプル説明
このサンプルでのキーになる記述は
getline()関数です。中をよく見ると
cin.get()関数(つまり1文字を入力からとってくる)関数をチェックして
最大値を超えるか、EOFが来るか、改行があれば入力終了という記述になってます。つまり
行というのは、1文字1文字の集合体であるという概念をそのまま記述したものです。
K&Rでは
cin.get()関数は
getchar()関数で表現されます。
getline()関数はC言語では標準関数でも用意されています。ですので、このサンプルは
標準関数の実装を簡易的に説明したもの、となっています。
K&Rではこのようなサンプルが数多く出てきます。
さて、
getline()関数を
C++のSTLを使って記述した場合、このサンプルは以下のようなものが一般的です。
ソース紹介
CPPファイルに記述
#include <iostream>
#include <string>
using namespace std;
int main()
{
string max_str;
string str;
while (getline(cin, str)) {
if (str.size() > max_str.size()) {
max_str = str;
}
}
if (max_str.size() > 0) {
cout << max_str.size() << "文字" << endl;
cout << max_str << endl;
}
else {
cout << "入力がありません" << endl;
}
return 0;
}
このように
C++の
stringを使うと、驚くように簡潔に書けます。もう
MAXLINEも
copy()関数も必要ではありません。
stringはもし長い行が出てきたら、内部でバッファのサイズを広げてくれます。
しかし。
K&Rにおける
getline()関数があるからこそ
stringの偉大さがわかります。ここは重要なところです。
K&Rでの記述
元になったのは
第1章:やさしい入門に記述されています。
文字配列の説明のところです。