K&R 演習1-16 解答 (プログラミング言語C 第2版)

スポンサーリンク

鍛錬 174

K&R 演習1-16 解答 (プログラミング言語C 第2版)

「一番長い行を印字するプログラムのmainルーチンを書き直して、任意の長さの入力行群の長さ、およびテキストのできるだけ多くの部分を正しく印字できるようにせよ」という問題です。
 
プログラム

以下は、任意の長さの入力行群の長さ、およびテキストのできるだけ多くの部分を正しく印字するプログラム kr_1_16.c です。

※ 本に記載されている getline() 関数について、gcc でコンパイルした際に、Linux の端末等で実行可能なコマンド getline と同じ名前であることが影響して、次に示す通りコンパイルがエラーとなります。
よって、以下に示すプログラム kr_1_16.c では、getline() を my_getline() と関数の名前を変更しています。

コンパイルエラー画面

***@ubuntu:~/***/test/c$ 
***@ubuntu:~/***/test/c$ gcc -Wall -Wextra kr_1_16.c -o kr_1_16
kr_1_16.c:9:5: error: conflicting types for ‘getline’
 int getline(char line[], int maxline);
     ^
In file included from kr_1_16.c:3:0:
/usr/include/stdio.h:678:20: note: previous declaration of ‘getline’ was here
 extern _IO_ssize_t getline (char **__restrict __lineptr,
                    ^
kr_1_16.c:45:5: error: conflicting types for ‘getline’
 int getline(char s[], int lim)
     ^
In file included from kr_1_16.c:3:0:
/usr/include/stdio.h:678:20: note: previous declaration of ‘getline’ was here
 extern _IO_ssize_t getline (char **__restrict __lineptr,
                    ^

 

// include
#include <stdio.h>

// preprocessor
#define MAXLINE 1000

// prototype
int my_getline(char line[], int maxline);
void copy(char to[], char from[]);

// main
int main(void)
{
	int len;
	int max;
	char line[MAXLINE];
	char longest[MAXLINE];
	
	max = 0;
	while ((len = my_getline(line, MAXLINE)) > 0) {
		printf("入力行の長さ = %d\n", len);
		printf("入力行のテキスト = %s", line);
		printf("\n");
		
		if (len > max) {
			max = len;
			copy(longest, line);
		}
	}
	
	if (max > 0)
		printf("一番長い行 = %s", longest);
	
	return 0;
}

// =====================================
// @brief      行を取得し,その長さを返す
// @param[in]  lim  入力行の最大長
// @param[out] s    取得した行
// @return     i -> 取得した行の長さ
// @note       無し
// =====================================
int my_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';
	
	return i;
}

// ===================================
// @brief      文字列をコピーする
// @param[in]  from  コピー元の文字列
// @param[out] to    コピー先の文字列
// @return     無し
// @note       無し
// ===================================
void copy(char to[], char from[])
{
	int i;
	
	i = 0;
	while ((to[i] = from[i]) != '\0')
		++i;
}

 
実行結果

以下は、プログラム kr_1_16.c を実行後に文字列を入力して、挙動を確認しています。
複数の文字列を入力後は Ctrl+d を押下して EOF を送信し、プログラムを終了しています。

***@ubuntu:~/***/test/c$ 
***@ubuntu:~/***/test/c$ gcc -Wall -Wextra kr_1_16.c -o kr_1_16
***@ubuntu:~/***/test/c$ ./kr_1_16
He succeeded to step up.
入力行の長さ = 25
入力行のテキスト = He succeeded to step up.

Yes. You will succeed.
入力行の長さ = 23
入力行のテキスト = Yes. You will succeed.

My hair is red from the time of birth.
入力行の長さ = 39
入力行のテキスト = My hair is red from the time of birth.

After a while by pressing the enter key, the scene of the world has changed completely.
入力行の長さ = 88
入力行のテキスト = After a while by pressing the enter key, the scene of the world has changed completely.

Dear Sirs. I am steadily run.
入力行の長さ = 30
入力行のテキスト = Dear Sirs. I am steadily run.

一番長い行 = After a while by pressing the enter key, the scene of the world has changed completely.
タイトルとURLをコピーしました