作成したプログラムの失敗ケースはどんな場合か?

フォーラム(掲示板)ルール
フォーラム(掲示板)ルールはこちら  ※コードを貼り付ける場合は [code][/code] で囲って下さい。詳しくはこちら
HelloW

作成したプログラムの失敗ケースはどんな場合か?

#1

投稿記事 by HelloW » 4ヶ月前

お世話になります。

すみません。「I」(大文字のアイ)と「l」(小文字のエル)と「i」(小文字のアイ)の文字がいずれか1つ以上含まれる場合は「caution」を出力し、そうでない場合は入力した文字列をそのまま表示するプログラムを作りたいのですが、あるケースの場合、上記の動作をしない場合があるみたいです。(作ったプログラムをテストするプログラムにかけたら失敗ケースが1つありました。)

考えましたが、どんな場合に上記の動作をしないのかがわからないので、教えてください。
どうかよろしくお願いします。

コード:

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

int main()
{
	//・1 行目には大文字小文字を含む半角英字アルファベットで構成される文字列 S
	//・入力は 1 行となり、末尾に改行を1つ含みます。
	char S[102];
	scanf("%s", S);

	//テスト
	//printf("%s", S);

	//Iかiかlが入力されたらcaution	 
	for (int i = 0; i < sizeof(S); i++)
	{
		if (S[i] == 'i' || S[i] == 'l' || S[i] == 'I')
		{
			printf("caution");
			break;
		}
	}

	//Iもiもlも入力されなかったら、入力された文字列をそのまま表示
	int counter = 0;
	for (int i = 0; i < sizeof(S); i++)
	{
		if (S[i] != 'i' && S[i] != 'l' && S[i] != 'I')
		{
			counter++;
		}

		if (counter == sizeof(S))
			printf("%s", S);
	}

	printf("\nstop");
	system("pause");
	return 0;
}

maru
記事: 149
登録日時: 7年前

Re: 作成したプログラムの失敗ケースはどんな場合か?

#2

投稿記事 by maru » 4ヶ月前

for文で回す回数が間違っています。sizeof(S)は102になり、文字列長ではありません。
そのため、文字列長が101未満の場合、配列Sに不定値が残ります。
オフトピック
文字列長102以上の場合、深刻な問題を引き起こす可能性があります。

かずま

Re: 作成したプログラムの失敗ケースはどんな場合か?

#3

投稿記事 by かずま » 4ヶ月前

HelloW さんが書きました:
4ヶ月前
考えましたが、どんな場合に上記の動作をしないのかがわからないので、教えてください。
char S[102]; は初期化されていないので、何が入っているかわかりません。

scanf("%s", S); で abc を入力すると、
S[0] = 'a', S[1] = 'b', s[2] = 'c', s[3] = '\0' と
先頭 4バイトだけ値が設定されます。
残りの S[5]~S[101] の 98バイトに 'I', 'i', 'l' が
入っている可能性があります。

その場合、sizeof(S) を使って配列全体を探索すると、
入力の abc に Iil が含まれていないにもかかわらず
caution が表示されてしまいます。

入力文字列の最後で探索を終了するために次のように変更してください。

コード:

    for (int i = 0; S[i] != '\0'; i++)
また、最初の forループで Iil の有無が分かるので、
二度目の forループは要りません。

コード:

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

int main(void)
{
	char S[102];
	scanf("%s", S);
	int i;
	for (i = 0; S[i] != '\0'; i++) {
		if (S[i] == 'i' || S[i] == 'l' || S[i] == 'I') {
			printf("caution");
			break;
		}
	}
	if (S[i] == '\0') printf("%s", S);
	printf("\nstop");
	system("pause");
	return 0;
}
さらに、<string.h> には strpbrk という関数があるので、
次のように書くこともできます。

コード:

#include <stdio.h>   // scanf, puts, printf
#include <string.h>  // strpbrk
#include <stdlib.h>  // system

int main(void)
{
	char S[102];
	if (scanf("%101s", S) != 1) return 1;
	puts(strpbrk(S, "iIl") ? "caution" : S);
	printf("stop");
	system("pause");
	return 0;
}

NightShift
記事: 10
登録日時: 5ヶ月前

Re: 作成したプログラムの失敗ケースはどんな場合か?

#4

投稿記事 by NightShift » 4ヶ月前

HelloWです。(すみません。入力した ユーザー名 は既に使用されています。他のユーザー名をご入力ください。と出るので、ログインしました。)

maruさん、かずまさん

ご説明をありがとうございました。
解決しました。

>かずまさん
ご丁寧に分かりやすい説明を感謝申し上げます。

返信

“C言語何でも質問掲示板” へ戻る