計算機科学のブログ

C - 小さなツール - 1つのことだけをうまくやる - コマンドラインオプション, ライブラリ, unistd.h, getopt関数

Head First C ―頭とからだで覚えるCの基本David Griffiths(著)、 Dawn Griffiths(著)、 中田 秀基(監修)、 木下 哲也(翻訳)、 O’Reilly Media)の3章(小さなツール - 1つのことだけをうまくやる)、p.151(ピザの一切れ)の解答を求めてみる。

Makefile

all: order_pizza
	./order_pizza && \
	./order_pizza -d home && \
	./order_pizza -t && \
	./order_pizza -d home -t A B && \
	./order_pizza -td home A B && \
	./order_pizza -d

order_pizza: order_pizza.c
	cc order_pizza.c -o order_pizza

コード

order_pizza.c

#include <stdio.h>
#include <unistd.h>
#include <stdbool.h>

int main(int argc, char *argv[])
{
    puts("-----");
    char *delivery = "";
    bool thick = false;
    char ch;
    while ((ch = getopt(argc, argv, "d:t")) != EOF)
    {
        switch (ch)
        {
        case 'd':
            delivery = optarg;
            break;
        case 't':
            thick = true;
            break;
        default:
            fprintf(stderr, " Unknown option: '%s'\n", optarg);
            return 1;
        }
    }
    argc -= optind;
    argv += optind;

    if (thick)
    {
        puts("Thick crust.");
    }
    if (delivery[0])
    {
        printf("to be delivered %s.\n", delivery);
    }
    for (size_t count = 0; count < argc; count++)
    {
        puts(argv[count]);
    }
}

入出力結果(Terminal, Zsh)

% make
./order_pizza && \
	./order_pizza -d home && \
	./order_pizza -t && \
	./order_pizza -d home -t A B && \
	./order_pizza -td home A B && \
	./order_pizza -d
-----
-----
to be delivered home.
-----
Thick crust.
-----
Thick crust.
to be delivered home.
A
B
-----
Thick crust.
to be delivered home.
A
B
-----
./order_pizza: option requires an argument -- d
 Unknown option: '(null)'
make: *** [all] Error 1
%