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

スポンサーリンク

鍛錬 307

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

文字列 s2 の任意の文字と等しい文字列 s1 の最初の文字位置を返す関数 any(s1, s2) を書け。ただし,一致する文字がなければ -1 を返す。(標準ライブラリ関数 strpbrk は同じ働きをもつが,その位置へのポインタを返す。)

B.W.カーニハン D.M.リッチー 石田晴久 訳 『プログラミング言語C 第2版 ANSI 規格準拠』, (共立出版, 2017), pp.59.

スポンサーリンク

プログラム

以下は、文字列 s2 中に存在するいずれかの文字に等しい文字の位置を s1 から検索するプログラム、kr_2_5.c です。

文字列 s1 と s2 については、次の文字列を指定しています。

s1:DYD_EYE*AYA-BYB+CYC
s2:ABC

// include
#include <stdio.h>

// preprocessor
#define MAX_LINE 256  // 格納可能な文字列の最大長

// prototype
int any(char s1[], char s2[]);
void copy(char from[], char to[]);

// main
int main(void)
{
	char s1[MAX_LINE] = "DYD_EYE*AYA-BYB+CYC";
	char s2[MAX_LINE] = "ABC";
	int ret;
	
	ret = any(s1, s2);
	if (ret == -1) {
		printf("ERROR,s2(\"%s\") のいずれも s1(\"%s\") に存在しない\n", s2, s1);
		return -1;
	}
	
	printf("---length---------------------------\n");
	printf("            1         2         3\n");
	printf("   123456789012345678901234567890\n");
	printf("---||||||||||||||||||||||||||||||---\n");
	printf("s1:%s\n\n", s1);
	printf("の %d 番目に\n\n", ret);
	printf("s2:%s\n\n", s2);
	printf("のいずれかが存在する\n");
	
	return 0;
}

// =========================================================================
// @brief     文字列s2中のいずれかの文字に等しい文字の位置を,s1から検索する
// @param[in] s1  被チェック文字列
// @param[in] s2  除去文字列
// @return    i  -> 文字位置
// @return    -1 -> エラー
// @note      無し
// =========================================================================
int any(char s1[], char s2[])
{
	char tmp[MAX_LINE] = "";
	int tmp_count;
	int s2_count;
	int i;
	
	tmp_count = 0;
	s2_count = 0;
	
	for (i = 0; s2[s2_count] != '\0'; i++) {
		// 検索対象文字に一致しない場合
		if (s1[i] != s2[s2_count]) {
			// 被チェック文字列が終端の場合
			if (s1[i] == '\0') {
				tmp[tmp_count] = '\0';
				copy(tmp, s1);
				s2_count++;
				tmp_count = 0;
				i = 0;
				i--;
			}
			else {
				tmp[tmp_count++] = s1[i];
			}
		}
		// ret:文字位置(文字位置 = ポインタ + 1)
		else
			return i + 1;
	}
	
	return -1;
}

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

実行結果

s2 を “ABC” に設定した場合

以下は、プログラム kr_2_5.c を実行して、文字列 s2「ABC」のいずれかの文字に等しい文字の位置を s1 から検索しています。

kr_2_5.c から抜粋

int main(void)
{
	char s1[MAX_LINE] = "DYD_EYE*AYA-BYB+CYC";
	char s2[MAX_LINE] = "ABC";
	int ret;
	
	ret = any(s1, s2);

実行結果

***@ubuntu:~/***/test/c$ 
***@ubuntu:~/***/test/c$ gcc -Wall -Wextra kr_2_5.c -o kr_2_5
***@ubuntu:~/***/test/c$ ./kr_2_5
---length---------------------------
            1         2         3
   123456789012345678901234567890
---||||||||||||||||||||||||||||||---
s1:DYD_EYE*AYA-BYB+CYC

の 9 番目に

s2:ABC

のいずれかが存在する

s2 を “CAB” に設定した場合

以下は、プログラム kr_2_5.c を実行して、文字列 s2「CAB」のいずれかの文字に等しい文字の位置を s1 から検索しています。

kr_2_5.c から抜粋

int main(void)
{
	char s1[MAX_LINE] = "DYD_EYE*AYA-BYB+CYC";
	char s2[MAX_LINE] = "CAB";
	int ret;
	
	ret = any(s1, s2);

実行結果

***@ubuntu:~/***/test/c$ 
***@ubuntu:~/***/test/c$ gcc -Wall -Wextra kr_2_5.c -o kr_2_5
***@ubuntu:~/***/test/c$ ./kr_2_5
---length---------------------------
            1         2         3
   123456789012345678901234567890
---||||||||||||||||||||||||||||||---
s1:DYD_EYE*AYA-BYB+CYC

の 17 番目に

s2:CAB

のいずれかが存在する

s2 を s1 に存在しない “RST” に設定した場合

以下は、プログラム kr_2_5.c を実行して、文字列 s2「RST」のいずれかの文字に等しい文字の位置を s1 から検索しています。

kr_2_5.c から抜粋

int main(void)
{
	char s1[MAX_LINE] = "DYD_EYE*AYA-BYB+CYC";
	char s2[MAX_LINE] = "RST";
	int ret;
	
	ret = any(s1, s2);

実行結果

***@ubuntu:~/***/test/c$ 
***@ubuntu:~/***/test/c$ gcc -Wall -Wextra kr_2_5.c -o kr_2_5
***@ubuntu:~/***/test/c$ ./kr_2_5
ERROR,s2("RST") のいずれも s1("DYD_EYE*AYA-BYB+CYC") に存在しない
タイトルとURLをコピーしました