25
24

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

getline() の使い方【trackのC++】

Last updated at Posted at 2021-04-27

前文

こんにちは。
22卒でエンジニア就活をしているしがない大学生です。

エンジニア志望で就職活動をしている皆様は、
trackを使ったコーディングテストを受験することが度々あると思います。
多くのプログラミング言語に対応しており、多くの企業さんが使われていますよね。

私はC++を使って問題を解くのですが、
そこで入力のテンプレートとして使われているのが、getline関数。

なにこれ!入力ってcinじゃねぇの!?
getline関数ってどう使うんだよ!?

ってな感じで、
問題を考える前に、入力を処理するのに解答時間の半分くらい使ってしまいました。

この記事は、
私のような人を生まないための礎となればという思いで、
書き残すものであります。

使い方

サンプルコード

例えば、
入力が半角の空白で区切られているときは以下のようなコードになります。

sumple.cpp
#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'を使った場合、決められた入力しか受け付けません。
例えば、

input1
int a;
cin >> a;

上記のような使い方や、

input_array
int a[5];
for (int i = 0; i < 5; ++i) cin >> a[i];

上記のような使い方が主になると思われます。

まあこれでも入力処理はできます。

が、
それは、入力が全て妥当なものであるという保証がされている場合のみになります。

つまり、
想定外の入力がされた場合対応できないんですね。

上記のinput1は数値1つしか取得しないし、
input_arrayは5つの数値しか取得しないわけです。

いやまあ当たり前なんですが。

競技プログラミングでは、テストケースの全ての妥当性が担保されているので、
これでも問題はないです。

しかし、
実務におけるプログラミングでは、入力にバグがあることもあるのかなと思います。
例えば、
入力の途中にノイズが入ったりした場合や、
仕様で特殊な終了文字が決められている場合が考えられるでしょうか。

そういった場合でも、
getline関数はとりあえず入力されたものはすべて取得します。
比較的楽に実装することができるでしょう。

結論

想定外の入力に対処がしやすいのかなと思いました。
知らんけど。

最後に

ということで、
本記事ではgetline関数の使い方を紹介しました。

少しでも皆様のエンジニア就活の助けになったなら嬉しいです。

では。

参考文献

getline - cpprefjp C++日本語リファレンス

25
24
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
25
24

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?