2013年5月10日金曜日

開発環境

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

その他参考書籍

演習 5-12.

コード

sample.c

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

#define LINELENGTH 50
#define TABLENGTH 8
#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, c;
    if (argc <= 1)
        for (i = 1; i <= LINELENGTH; i++)
            if (i % TABLENGTH)
                tab[i] = NO;
            else
                tab[i] = YES;
    else if (argc == 3 && *argv[1] == '-' && *argv[2] == '+') {
        pos = atoi(&(*++argv)[1]);
        c = atoi(&(*++argv)[1]);
        for (i = 1; i <= LINELENGTH; i++)
            if (i != pos)
                tab[i] = NO;
            else {
                tab[i] = YES;
                pos += c;
            }
    } 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)

detab

$ printf "\t#\n"
 #
$ printf "\t#\n" | ./a.out
        #
$ printf "\t#\n" | ./a.out 1
 #
$ printf "\t#\n" | ./a.out 2
  #
$ printf "\t#\n" | ./a.out 9
         #
$ printf "\t#\n" | ./a.out 10
          #
$ printf "\t#\t#\t#\t#\t#\n" | ./a.out -5 +10
     #         #         #         #         #
$ printf "\t#\t#\t#\t#\t#\n" | ./a.out -10 +5
          #    #    #    #    #
$

0 コメント:

コメントを投稿