C++で競プロ用の環境を構築


環境情報

key value
PC本体 MacBook air
OS macOS Catalina
エディタ VS Code

本記事の目的

競技プログラミングで使えるレベルの、C++のテスト環境を構築する。
理想はこんな感じ↓
1. 画面を下記のように分割。
[画面左] 実行コード
[画面右] 入力値
2. ショートカットで[コンパイル, 実行, 実行ファイルの削除]

現状は、ショートカットではないけど2まで出来上がった!

新たに作った「goc」コマンドでサクッと実行できてますね。

[経緯]
- AtCoderを始めたがPythonの実行時間エラーに悩まされ、C++に手を出すに至った。
- C++について基本構文しか知らないけど、とにかく上に行きたい。
- あれ、C++ってローカルで実行するのめんどい?

設定手順

1. gcc動作環境が欲しい方は導入

参考記事1を見て、導入してください。
素敵な記事なのでさくっとできるはず!

2. 全処理を行ってくれるshellファイルを作成

$ cd /usr/local/bin
$ touch goc.sh
# goc.shを実行できるように、ファイルの権限を書き換える。(参考記事2)
$ chmod u+x goc.sh

goc.shファイルに下記の内容を入力(vimでもcode goc.shでもお好きに)

goc.sh
#!/bin/bash
g++ $1.cpp -o $1 && ./$1 && rm ./$1

※処理内容($1はgocコマンドの第一引数、つまりファイル名)
→ 「g++ test.cpp -o test」 ... test.cppファイルをtestという実行ファイル名にコンパイル
→ 「./test」 ... 実行ファイルの実行
→ 「rm ./test」 ... 実行ファイルの削除

3. shellファイルをコマンド化

コマンド化には参考記事1で使っていたln(シンボリックリンク)で対応する。

$ ln -s /usr/local/bin/goc.sh /usr/local/bin/goc

環境変数で/usr/local/binが設定されているおかげで、どこからでもgocコマンドとして使用ができるようになる。
(設定しなくてもgoc.shならどこからでも使える)

4. 第一フェーズ完了

これでもうコマンドが使えるはずだ。
好きなところで、下記のファイルを作成してコマンドを打ってみよう。

test.cpp
#include <iostream>
using namespace std;

int main(){
    cout << "Hello World!!" << endl;
} 

ファイルのあるディレクトリで、下記のコマンドを打てば "Hello World!!"が出るはずだ。
$ goc test

続いて、入力ファイルを読み込めるようにしていく。

5. 実行ファイルの書き換え

先に書いたtest.cppを雛形となるように下記の通り書き換える。

test.cpp
#include <iostream>
#include <fstream>
using namespace std;

//solveメソッド内には、実際に提出するソースを書き込む
void solve(){
    string word1, word2;

    cin >> word1;
    cin >> word2;
    cout << word1 << " " << word2 <<endl;
    cout << "Hello World!!" << endl;
}

int main(int argc, char* argv[]){
    string file_name = argv[1];
    std::ifstream in(file_name+"_input");
    std::cin.rdbuf(in.rdbuf());

    solve();
} 

ここでのmain関数には下記2点の役割がある。

  • 入力ファイル名の決定 ※「{第一引数}+"_input"」というファイル名とした
  • 入力ファイルの一行一行を標準入力として受け取る

6. コマンドの修正

実行ファイルの引数に「入力ファイル名」の先頭文字を指定する。
という仕様にしたので、goc.shファイルも書き換えてやる必要がある。

goc.sh
#!/bin/bash
g++ $1.cpp -o $1 && ./$1 $1&& rm ./$1

入力ファイルは「{ソースファイル名}+"_input"」という命名規則にした。
例えば、「test.cpp」ファイルの入力ファイル名は「test_input」となる。

7. 動作確認

ここまでお疲れ様です。
早速動作確認のため、下記のファイルをtest.cppファイルと同じディレクトリに作成しましょう。

test_input
Hello
World
!!!

コマンドは変わらず下記の通りです。

$ goc test
>>> Hello World
>>> Hello World!!

やったね!!!
以上!!!!!!

残タスク:ショートカットでの実行を試みたが...

Visual studio codeで競プロ環境構築[mac OS]を参考にショートカットによるコンパイルを試したが、

cpp.shを実行する段階で、$1$fも値がなさそうで、エラーが発生した。
残念ながらここから進展はしなかった。

誰か$fがどこで定義されてるのか、$1(実行時引数)はどうやってショートカットでの実行で渡せるのか、教えてください。。。

参考記事

  1. Visual studio codeで競プロ環境構築[mac OS]
    https://qiita.com/EngTks/items/ffa2a7b4d264e7a052c6
  2. Linuxの権限確認と変更(chmod)(超初心者向け)
    https://qiita.com/shisama/items/5f4c4fa768642aad9e06
  3. [C++] 基本的なコンパイル方法 [C++初心者] https://qiita.com/okateim/items/e170792bb0d435885e58
  4. コンパイルして実行するシェルスクリプト C,C++
    https://qiita.com/koshitake2m2/items/d188d70f549ae0138a75
  5. cin でテキストファイルから読み込み
    https://qiita.com/_meki/items/559ff91f3e695de5600f