「ふつ☆りな」第6章の練習問題(1)続々

飽きたので答え見ました。\(^o^)/

解答例が本に見つからないと前に書きましたが、著者のWebサイトからサンプルコードをダウンロードできる形式でした。

問題

タブ文字('\t')を「\t」、改行を「'$'+改行」として出力するcatコマンドを書きなさい。

解答例の概略

検索文字と一致すれば、置換後の文字をfputsで書き出す。一致しなければ元の文字をputcharで書き出す。

文字列を作って返す関数を作るよりも、評価次第どんどん書き出す関数を作ればよかったようです。

書き直してみる

解答例を参考にしつつ、自分のコードを書き直しました。

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

static void do_cat(FILE *f);
static void die(const char *s);

int main(int argc, char *argv[])
{
	int i;

	if(argc < 2){
		do_cat(stdin);
	} else {
		for(i = 1; i < argc; i++){
			FILE *f;
			
			f = fopen(argv[i], "r");
			if(!f){
				perror(argv[i]);
				exit(1);
			}
			do_cat(f);
			fclose(f);
		}
	}
	return 0;
}

static void do_cat(FILE *f)
{
	int c;
	int before_t = '\t';
	char after_t[] = "\\t";
	int before_n = '\n';
	char after_n[] = "$\n";

	for(;;){
		if ((c = (fgetc(f))) == EOF){
			break;
		}
		if (c == before_t){
			if ((fputs(after_t, stdout)) == EOF){
				die("書き込めません。");
			} 
		} else if (c == before_n){
			if ((fputs(after_n, stdout)) == EOF){
				die("書き込めません。");
			}
		} else {
			if (putchar(c) < 0){
				die("書き込めません。");
			}
		}
	}
}

static void die(const char *s)
{
	perror(s);
	exit(1);
}

なるほど。

ちなみに、昨日の自分の誤答で、なぜ先頭1文字が欠けるのかは、まだ理解していません。

が、とりあえず前へ進むことに。