Hatena::Groupgeneration1986

仮想化済み古代魚

 | 

2008-05-10

K&R 演習1-18解けたよー

15:05

//K&R P38 演習1-18 改行前のタブ、空白、空白行を削除して印字
#include <stdio.h>
#define MAXLINE 1000	//入力される行の最大長

int getline(char line[], int maxline);
int add(char to[], char from[], int end);	//toが先である点注意
void clean(char s[]);

int main(void)
{
	char line[MAXLINE];	//現在の入力行の文字列
	int i;
        char save[5000];	//4000文字まで入る保管用配列
	int end;

	for (i = end = 0; getline(line, MAXLINE) > 0; ++i){
		clean(line);
		printf("cleanの結果:%s", line);
		end = add(save, line, end);
	}

	printf("処理後の文字列は%s", save);
	
	return 0;
}

//配列sに行を格納して長さを返す
int getline(char s[], int lim)
{
	int c, i;
	
	for (i=0; i<lim-1 && (c=getchar()) != EOF && c != '\n'; ++i)
		s[i] = c;	//改行まで文字を配列に入れる
	if (c == '\n'){
		s[i] = c;	//行の最後が改行なら改行も格納
		++i;		//その後ろへ移動
	}
	s[i] = '\0';		//改行の後ろに\0を格納。末尾の目印
	return i;
}

//文字配列を保存末尾に追加する。\0の格納場所を返す
int add(char to[], char from[], int end)	//to, from, endは仮引数
{
	int i;
	
	for (i = 0; from[i] != '\0'; ++i)
		to[end+i] = from[i];	//\0の次にfromの内容を入れる
                		
	printf("『%d文字格納』\n", i);
		end = end + i;
		to[end] = '\0';
		
		return end;
}

void clean(char s[])
{
	int i, feof;
	feof = 1;	//EOFフラグ。倒れなければEOF
	
	for (i = 0; s[i] != '\0'; ++i){
		if (s[i] == '\n'){
			feof = 0;	//\nがあったらeof行ではない=フラグ倒し
			printf("EOFではない\n");
		}
	}
			
	printf("s[%d] = \\0 まで移動\n", i);
	i--;
	printf("s[%d]に移動\n", i);

	for (; (s[i] == '\t'||s[i] =='\n'||s[i] ==' ') && i > 0; --i){	
		s[i] = '\0';
		printf("\\t, \\n, または半角スペース削除\n");
	}
	
	if (feof == 0 && (s[i] != '\t') && (s[i] !=' ') && (s[i] != '\n')){
		i++;
		s[i] = '\n';
		i++;
		s[i] = '\0';
		printf("空白行ではない\n");
	}
	else if (s[i] == '\n')
		s[i] = '\0';
}

 文字配列を操作するのが面倒で面倒で……。解けるまでやたらと時間が掛かってしまいました。これよりもっと高度な事やってるOffice系ソフトを最初に作った人は偉いですね。

トラックバック - http://generation1986.g.hatena.ne.jp/oldfish/20080510
 |