ページ 1 / 1
fgetsで取得した文字列の末尾の判定
Posted: 2019年3月23日(土) 17:17
by orica
入力値を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;
}
Re: fgetsで取得した文字列の末尾の判定
Posted: 2019年3月23日(土) 18:25
by みけCAT
orica さんが書きました: ↑6年前
配列の中身をsprintfで表示すると、"."で終わっている場合でも改行までは空白の何かが入っているようで
「空白の何か」が何かわかりますか?
そもそも、本当に入っているのですか?
提示されたコードから未定義動作を起こす行int str_length = strlen(str);を削除し、
書式%cを%dか%02xに変更して文字コードを出力すると、正体がわかるかもしれません。
orica さんが書きました: ↑6年前
配列の中身をsprintfで表示するところまで作成したコードは以下になります
このコードは、未初期化の自動変数strの値をstrlen関数内で計算に使用するため、未定義動作になります。
また、「sprintfで表示する」と書かれているにもかかわらず、sprintfが使用されていないようです。
オフトピック
現在、この掲示板の仕様により、
地の文中の[i]は終了タグがなくても文字を斜体にするタグと解釈されてしまいます。
ソースコードを提示する時は、codeタグで囲んでください。
そうすると、半角空白によるインデントも反映され、見やすくなります。
Re: fgetsで取得した文字列の末尾の判定
Posted: 2019年3月24日(日) 10:44
by orica
ご返答頂きましてありがとうございます。誤記・無駄な表記があり失礼いたしました。
おかげさまで、末尾に何が入っているか判明しました。正体は”改行”と”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で取得した文字列の末尾の判定
Posted: 2019年3月25日(月) 01:30
by かずま
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");
}
Re: fgetsで取得した文字列の末尾の判定
Posted: 2019年3月25日(月) 12:02
by orica
なるほど、とてもスマートですね!
他の角度からのアドバイスも大変参考になり、ありがたく思います。
レスありがとうございました。#^^#
Re: fgetsで取得した文字列の末尾の判定
Posted: 2019年3月26日(火) 22:11
by かずま
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' でもない場合は何も出力しない
という仕様でよいのでしょうか?
Re: fgetsで取得した文字列の末尾の判定
Posted: 2019年3月28日(木) 00:40
by orica
またもやスマートな解をありがとうございます!
しかし、、自分の知識が乏しく、膝を打つに至らず。。
While(条件){} ではない表記ってあるのですね。。この(条件)部分の式も、str[--i] == '.' という表記も初めて出会いました。。(&&,!=はさすがに存じておりますが!)
もしよろしければ理解のためのヒントを頂けると助かります。
Re: fgetsで取得した文字列の末尾の判定
Posted: 2019年3月28日(木) 18:08
by かずま
orica さんが書きました: ↑6年前
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 さんが書きました: ↑6年前
この(条件)部分の式も、str[--i] == '.' という表記も初めて出会いました。。
コード:
if (str[--i] == '.')
は
i = i - 1;
if (str[i] == '.')
と同じです。
コード:
if (str[i--] == '.')
は
int t = i;
i = i - 1;
if (str[t] == '.')
と同じです。