前文
こんにちは。
22卒でエンジニア就活をしているしがない大学生です。
エンジニア志望で就職活動をしている皆様は、
trackを使ったコーディングテストを受験することが度々あると思います。
多くのプログラミング言語に対応しており、多くの企業さんが使われていますよね。
私はC++を使って問題を解くのですが、
そこで入力のテンプレートとして使われているのが、getline
関数。
なにこれ!入力ってcin
じゃねぇの!?
getline
関数ってどう使うんだよ!?
ってな感じで、
問題を考える前に、入力を処理するのに解答時間の半分くらい使ってしまいました。
この記事は、
私のような人を生まないための礎となればという思いで、
書き残すものであります。
使い方
サンプルコード
例えば、
入力が半角の空白で区切られているときは以下のようなコードになります。
#include <algorithm>
#include <bitset>
#include <cassert>
#include <cctype>
#include <cfloat>
#include <climits>
#include <cmath>
#include <cstdio>
#include <deque>
#include <iomanip>
#include <iostream>
#include <list>
#include <map>
#include <queue>
#include <random>
#include <set>
#include <stack>
#include <string>
#include <unordered_set>
#include <vector>
#include <sstream>
using namespace std;
int main() {
string line, s;
while (!cin.eof()) {
getline(cin, line);
stringstream line2(line);
int i = 0;
while( getline(line2, s, ' ') ) {
if ( i == 0 ) {
if ( s == "case 1" ) {
} else if ( s == "case 2" ) {
}
} else if ( i == 1 ) {
} else if ( i == 2 ) {
} else {
}
++i;
}
}
}
解説
string line, s;
while (!cin.eof()) {
getline(cin, line); // 入力文字列を取得しlineに格納
stringstream line2(line); // stringstream型にする
int i = 0;
while( getline(line2, s, ' ') ) { // stringstream型の入力文字列を半角空白で分割しsに格納
if ( i == 0 ) {
// 分割した最初の文字列に対する処理
// sに分割した文字列が格納されているのでそれを使って処理を実装
if ( s == "case 1" ) {
} else if ( s == "case 2" ) {
︙
}
} else if ( i == 1 ) {
// 分割した2番目の文字列に対する処理
} else if ( i == 2 ) {
// 分割した3番目の文字列に対する処理
︙
} else {
}
++i;
}
getline
関数について
getline
関数の使い方を解説します。
入力取得
第一引数にcin
、
第二引数に入力文字列を格納する変数を入れることで、
入力を取得することができます。
getline(cin, line);
上記ではline
に入力文字列を格納しています。
文字列分割
第一引数にstringstream
型の変数、
第二引数に分割した文字列を格納する変数、
第三引数に何で分割するかを入れることで、
文字列を分割してその一つ一つ取得することができます。
getline(line2, s, ' ');
上記では半角空白で分割した文字列を変数s
に格納しています。
getline(line2, s, ',');
上記ではコンマで分割した文字列を変数s
に格納しています。
何がありがたいか
入力をそのまま受け取る
例えば、入力が、
「空白で区切られた任意の要素数の数字の配列が与えられる」場合。
つまり、数字は1個だけかもしれないし、2個かもしれないし、100個かもしれない。
競技プログラミングにおいては、
5 ←配列の要素数
1 2 3 4 5 ←配列
上記のような感じで配列の要素数がまず与えられ、
その後、その数だけの要素を持つ配列が与えられたりするのですが。
trackの問題においては、
1 2 3 4 5
上記のようにいきなり配列から与えられたり、
1 2 3 4 5
6 7
8 9 10 11 12
任意の要素数の配列を任意の行数入力として与えられたりします。
そんな場合でも、
getline
関数はとりあえず入力されたものはすべて取得します。
問題なく、実装することが可能です。
妥当でない入力でも対応できる
'cin'を使った場合、決められた入力しか受け付けません。
例えば、
int a;
cin >> a;
上記のような使い方や、
int a[5];
for (int i = 0; i < 5; ++i) cin >> a[i];
上記のような使い方が主になると思われます。
まあこれでも入力処理はできます。
が、
それは、入力が全て妥当なものであるという保証がされている場合のみになります。
つまり、
想定外の入力がされた場合対応できないんですね。
上記のinput1
は数値1つしか取得しないし、
input_array
は5つの数値しか取得しないわけです。
いやまあ当たり前なんですが。
競技プログラミングでは、テストケースの全ての妥当性が担保されているので、
これでも問題はないです。
しかし、
実務におけるプログラミングでは、入力にバグがあることもあるのかなと思います。
例えば、
入力の途中にノイズが入ったりした場合や、
仕様で特殊な終了文字が決められている場合が考えられるでしょうか。
そういった場合でも、
getline
関数はとりあえず入力されたものはすべて取得します。
比較的楽に実装することができるでしょう。
結論
想定外の入力に対処がしやすいのかなと思いました。
知らんけど。
最後に
ということで、
本記事ではgetline
関数の使い方を紹介しました。
少しでも皆様のエンジニア就活の助けになったなら嬉しいです。
では。