2013年5月9日木曜日

開発環境

プログラミング言語C 第2版 ANSI規格準拠 (B.W. カーニハン D.M. リッチー (著)、 石田 晴久 (翻訳)、共立出版)の第5章(ポインタと配列)、5.10(コマンド行の引数)、演習5-11を解いてみる。

その他参考書籍

演習 5-11.

コード

sample.c

#include <stdio.h>
#include <stdlib.h>

#define LINELENGTH 50
#define TABLENGTH 4
#define YES 1
#define NO 0

void entab(char *tab);
void detab(char *tab);
void settab(int argc, char *argv[], char *tab);
int tabpos(int pos, char *tab);

int main(int argc, char *argv[])
{
    char tab[LINELENGTH + 1];
    
    settab(argc, argv, tab);
    // entab(tab);
    detab(tab);
    return 0;
}

void entab(char *tab)
{
    int c, pos, nb, nt;
    
    nb = 0;
    nt = 0;
    
    for (pos = 1; (c = getchar()) != EOF; pos++)
        if (c == ' ') {
            if (tabpos(pos, tab) == NO)
                nb++;
            else {
                nb = 0;
                nt++;
            }
        } else {
            for (; nt > 0; nt--)
                putchar('\t');
            if (c == '\t')
                nb = 0;
            else
                for (; nb > 0; nb--)
                    putchar(' ');
            putchar(c);
            if (c == '\n')
                pos = 0;
            else if (c == '\t')
                while (tabpos(pos, tab) != YES)
                    ++pos;
        }
}

void detab(char *tab)
{
    int c, pos;
    
    pos = 1;
    
    while ((c = getchar()) != EOF)
        if (c == '\t') {
            do {
                putchar(' ');
            } while (tabpos(pos++, tab) != YES);
        } else if(c == '\n') {
            pos = 1;
            putchar(c);
        } else {
            pos++;
            putchar(c);
        }
}

void settab(int argc, char *argv[], char *tab)
{
    int i, pos;
    if (argc <= 1)
        for (i = 1; i <= LINELENGTH; i++)
            if (i % TABLENGTH)
                tab[i] = NO;
            else
                tab[i] = YES;
    else {
        for (i = 1; i <= LINELENGTH; i++)
            tab[i] = NO;
        while (--argc > 0) {
            pos = atoi(*++argv);
            if (pos && pos <= LINELENGTH)
                tab[pos] = YES;
        }
    }
}

int tabpos(int pos, char *tab)
{
    if (pos > LINELENGTH)
        return YES;
    return tab[pos];
}

入出力結果(Terminal)

entab

$ echo '*  *   *    *     *
*     *    *   *  *'
*  *   *    *     *
*     *    *   *  *
$ echo '*  *   *    *     *
*     *    *   *  *' | ./a.out 1 2 3 4 5
*  *   *    *     *
*     *    *   *  *
$

detab

$ printf "*\t**\t***\t****
> ****\t***\t**\t*\n"
* ** *** ****
**** *** ** *
$ printf "*\t**\t***\t****
****\t***\t**\t*\n" | ./a.out
*   **  *** ****
****    *** **  *
$ printf "*\t**\t***\t****
****\t***\t**\t*\n" | ./a.out 1 2 3 4 5
* ** ***                                           ****
**** ***                                           ** *
$ printf "*\t**\t***\t****
****\t***\t**\t*\n" | ./a.out 5 4 3 2 1
* ** ***                                           ****
**** ***                                           ** *
$ printf "*\t**\t***\t****
****\t***\t**\t*\n" | ./a.out 10 20
*         **        ***                            ****
****      ***       **                             *
$

時間かかった割にはあんまりよく分かってなかったり。。

1 コメント :

galih n gumilarさんのコメント...

nice information.. Arigato

コメントを投稿