標準入出力の操作方法(Obj-C)


はじめに

「HackerRank」というプログラミングの問題を解くサイトがあります。
https://www.hackerrank.com

こちらのサイトでは「標準入力を取得する→問題を解く→解答結果を標準出力する」という流れで問題を解きます。

Objective-Cで標準入出力を操作する方法に手間取ったので、備忘録として残しておきます。

環境

  • OS:macOS High Sierra 10.13.1
  • Xcode:9.2

プロジェクトの作成

標準入出力を扱うには、コマンドラインツールのプロジェクトを作成します。

Xcodeを起動し、「Create a new Xcode project」をクリックします。

[macOS]タブにある「Command Line Tool」を選択して[Next]ボタンをクリックします。

あとは通常のプロジェクトと同様にして作成します。

標準入出力の実装(Obj-C)

コマンドラインツールのプロジェクトはほぼ空のメインファイルのみ存在します。

main.m(before)
#import <Foundation/Foundation.h>

int main(int argc, const char * argv[]) {
    @autoreleasepool {
        // insert code here...
        NSLog(@"Hello, World!");
    }
    return 0;
}

@autoreleasepool 内を以下のように書き換えます。

main.m(after)
#import <Foundation/Foundation.h>

int main(int argc, const char * argv[]) {
    @autoreleasepool {
        // 標準入力を取得する
        NSData *stdinData = [[NSFileHandle fileHandleWithStandardInput] availableData];
        NSString *stdinString = [[NSString alloc] initWithData:stdinData encoding:NSUTF8StringEncoding];

        // 標準入力を半角スペース区切りで配列に格納する
        NSArray *stdinArray = [stdinString componentsSeparatedByString:@" "];

        // TODO: 問題を解く
        // ここでは標準入力をそのまま解答とする
        NSArray *result = [stdinArray copy];

        // 解答を半角スペース区切りで文字列とする
        NSString *stdoutString = [result componentsJoinedByString:@" "];

        // 解答を標準出力する
        NSFileHandle *fileHandle = [NSFileHandle fileHandleWithStandardOutput];
        [fileHandle writeData:[stdoutString dataUsingEncoding:NSUTF8StringEncoding]];
        [fileHandle writeData:[@"\n" dataUsingEncoding:NSUTF8StringEncoding]];
        [fileHandle closeFile];
    }

    return 0;
}

標準入出力のデバッグ

通常のプロジェクトと同様、 ⌘R でデバッグします。

標準入力を受け付けるまで待機するので、画面右下のコンソールに値を入力して Enter を押下します。

今回は標準入力をそのまま標準出力しているため、標準入力と同じ値が太字で出力されます。

おわりに

今回作成したプロジェクトをGitHubで公開しました。
https://github.com/uhooi/StdinoutTemplates

実際の出力には NSLog を使うことがほとんどだと思いますし、標準入力は使わないので、このようなプログラミングサイトにしか使わないかもしれません。

参考リンク