K&R演習[1-20]

課題

入力されたタブを、次のタブ・ストップまでのスペースを埋める適当な数のブランク(空白)で置き換えるプログラムdetabを書け。

回答

#include <stdio.h>
#include <string.h>

typedef unsigned long int u8;
const int TAB_WIDTH = 4;        // タブ幅
void detab(u8 n, char *rslt);

/**
 * @fn      Main
 * @brief
 * @param
 * @return
 * @detail
 */
int main(void)
{
    int c, i = 0;
    char str[1000];

    while ((c = getchar()) != EOF) {        // 改行まで入力を取得する
        switch (c) {
            case '\t':                      // タブなら
                detab(i, str);              // 空白で埋める
                i += (TAB_WIDTH - (i % TAB_WIDTH)); // 文字数を進める
                break;

            case '\n':                      // 改行なら
                str[i] = '\n';              // コピーする
                str[i + 1] = '\0';          // 終端とする
                printf("%s", str);          // 印字する

                // 次に備えて文字列をクリア
                str[0] = '\0';
                i = 0;
                break;

            // タブ、改行以外の文字
            default:
                str[i] = c;
                i++;
                break;
        }
    }
}

/**
 *  @fn     detab
 *  @brief  次のタブストップまでを空白で埋める
 *  @param
 *  @return
 *  @detail
 */
void detab(u8 n, char *rslt)
{
    u8 i, a;

    // タブ幅から文字列長のタブ幅での剰余結果を引くことで、末尾に加えるスペース数を算出する
    a = TAB_WIDTH - (n % TAB_WIDTH);

    for (i = 0; i < a; i++) {
        rslt[n + i] = ' ';
    }
}

実行内容

        iu      hb

実行結果

    iu  hb

補足

コマンドプロンプトのタブは8文字。