fgetsで取得した文字列の末尾の判定

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

fgetsで取得した文字列の末尾の判定

#1

投稿記事 by orica » 3週間前

入力値をfgetsで取得した1行の文字列末尾が
"."で終わっているならFalse、"0"で終わっているならばTrueとしたいです

===
入力例:
122.3.4.
122.3.4.0

ほしい結果:
False
True
===

取得した1行の文字型配列を頭から評価していく方法を考えているのですが
配列の中身をsprintfで表示すると、"."で終わっている場合でも改行までは空白の何かが入っているようで
"0"との区別の方法がわかりません…

配列の中身をsprintfで表示するところまで作成したコードは以下になります

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

int main(void){

for(int p = 0; p < 10; p++)
{
char str[400];
int str_length = strlen(str);
fgets(str, sizeof(str), stdin);

int i = 0;
while( i <= 100 )
{
printf("%c\n",str);
if (str == '\0'){
printf("End\n");
break;
}
i = i+1;
}
}
return 0;
}

アバター
みけCAT
記事: 6115
登録日時: 8年前
住所: 千葉県
連絡を取る:

Re: fgetsで取得した文字列の末尾の判定

#2

投稿記事 by みけCAT » 3週間前

orica さんが書きました:
3週間前
配列の中身をsprintfで表示すると、"."で終わっている場合でも改行までは空白の何かが入っているようで
「空白の何か」が何かわかりますか?
そもそも、本当に入っているのですか?
提示されたコードから未定義動作を起こす行int str_length = strlen(str);を削除し、
書式%cを%dか%02xに変更して文字コードを出力すると、正体がわかるかもしれません。
orica さんが書きました:
3週間前
配列の中身をsprintfで表示するところまで作成したコードは以下になります
このコードは、未初期化の自動変数strの値をstrlen関数内で計算に使用するため、未定義動作になります。
また、「sprintfで表示する」と書かれているにもかかわらず、sprintfが使用されていないようです。
オフトピック
現在、この掲示板の仕様により、
地の文中の[​i]は終了タグがなくても文字を斜体にするタグと解釈されてしまいます。
ソースコードを提示する時は、codeタグで囲んでください。
そうすると、半角空白によるインデントも反映され、見やすくなります。
複雑な問題?マシンの性能を上げてOpenMPで殴ればいい!(死亡フラグ)

orica

Re: fgetsで取得した文字列の末尾の判定

#3

投稿記事 by orica » 3週間前

ご返答頂きましてありがとうございます。誤記・無駄な表記があり失礼いたしました。

おかげさまで、末尾に何が入っているか判明しました。正体は”改行”と”Null文字”で「空白」ではなかったです。。これで先に進めそうです!ありがとうございました。

*コードと実行結果も念のため残しておきます。

コード:

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

int main(void){

for(int p = 0; p < 2; p++)
{
    char str[400];
  /*  int str_length = strlen(str); */
    fgets(str, sizeof(str), stdin);
    
    int i = 0;
    while( i <= 100 )
    {
        printf("%d_ ",str[i]);
        if (str[i] == '\0'){
            printf("i=%d End\n",i); 
            break;
        }
        i = i+1;
    }
} 
return 0;
}


入力値:
122.3.4.
122.3.4.0

実行結果:
49_ 50_ 50_ 46_ 51_ 46_ 52_ 46_ 10_ 0_ i=9 End
49_ 50_ 50_ 46_ 51_ 46_ 52_ 46_ 48_ 10_ 0_ i=10 End

かずま

Re: fgetsで取得した文字列の末尾の判定

#4

投稿記事 by かずま » 3週間前

fgets を使っていないので、解答ではありませんが、
次のように書けば、改行の直前の文字で、
False や True を出すことができます。

コード:

#include <stdio.h>   // getchar, puts

int main(void)
{
	for (int c, d = 0; (c = getchar()) != EOF; d = c)
		if (c == '\n')
			if (d == '.') puts("False");
			else if (d == '0') puts("True");
}

orica

Re: fgetsで取得した文字列の末尾の判定

#5

投稿記事 by orica » 3週間前

なるほど、とてもスマートですね!
他の角度からのアドバイスも大変参考になり、ありがたく思います。
レスありがとうございました。#^^#

かずま

Re: fgetsで取得した文字列の末尾の判定

#6

投稿記事 by かずま » 3週間前

fgets を使った解答を書いてみました。

コード:

#include <stdio.h>   // fgets, puts

int main(void)
{
	char str[400];
	while (fgets(str, sizeof str, stdin)) {
		int i = 0;
		while (str[i] && str[i] != '\n') i++;
		if (i > 0)
			if (str[--i] == '.') puts("False");
			else if (str[i] == '0') puts("True");
	}
}
ただし、入力の文字数には、改行文字を除いて
398文字以下であるという制限があります。

行末の文字が '.' でも '0' でもない場合は何も出力しない
という仕様でよいのでしょうか?

orica

Re: fgetsで取得した文字列の末尾の判定

#7

投稿記事 by orica » 3週間前

またもやスマートな解をありがとうございます!
しかし、、自分の知識が乏しく、膝を打つに至らず。。
While(条件){} ではない表記ってあるのですね。。この(条件)部分の式も、str[--i] == '.' という表記も初めて出会いました。。(&&,!=はさすがに存じておりますが!)
もしよろしければ理解のためのヒントを頂けると助かります。

かずま

Re: fgetsで取得した文字列の末尾の判定

#8

投稿記事 by かずま » 3週間前

orica さんが書きました:
3週間前
While(条件){} ではない表記ってあるのですね。。
while文の構文は、
C++ では、「while (条件) 文」ですが、
C では、「while (式) 文」です。
C++ の「条件」はちょっと面倒なので、今は説明を控えます。

さて、C の「while (式) 文」を考えてみましょう。

while文は、「式」を評価してその値が 0 でなければ「文」を
実行し、「式」を再評価します。

「式」は、定数、変数、演算子を使った式などです。

コード:

	while (1) 文                     // 定数 1
	while (c) 文                     // 変数 c
	while (c == 'a') 文              // 等価演算子 ==
	while (c >= '0' && c <= '9') 文  // 論理AND演算子 &&
	while (isdigit(c)) 文            // 関数呼出し演算子 ()
	while (s[i]) 文                  // 添字演算子 []
	while (c = *p++) 文              // 代入演算子 =
「== や >= や && などの演算子を使った式」を評価した結果の値は、
0 または 1 です。

「文」は、複合文、式文、選択文、繰返し文などです。

コード:

	while (c) { a = 1; b = 3; }         // { 文の並び } は複合文
	while (c) a = 1;                    // a = 1 は式。a = 1; は式文
	while (c) if (b) a = 1;             // if から ; までが一つの選択文
	while (c) if (b) { a = 1; b = 3; }  // if から } までが一つの選択文
複合文の「文の並び」の文は 0個でも 1個でも構いません。
「{ }」は文が 0個の空文ですが、式文の式を省略した「;」も空文です。
orica さんが書きました:
3週間前
この(条件)部分の式も、str[--i] == '.' という表記も初めて出会いました。。

コード:

	if (str[--i] == '.')
は
	i = i - 1;
	if (str[i] == '.')
と同じです。

コード:

	if (str[i--] == '.')
は
	int t = i;
	i = i - 1;
	if (str[t] == '.')
と同じです。

返信

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