ページ 11

構造体を用いて表示させる

Posted: 2016年1月06日(水) 20:29
by KTN19
入力したものを構造体に格納して、それをまとめて出力するというものなのですが、うまくできません。。。
どうかご教授願えませんか?

コード:

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

typedef struct date_t{
	int year;
	int hyear;
	int month;
	int day;
	char day_of_week[20];
} today;
void print_day2( struct date_t today );

int main( void )
{
	struct date_t today;
	int i;
	char c, d[20];
	
	printf( "今日は... \n" );
	printf( "西暦" ); scanf( "%d", &today.year );
	printf( "平成" ); scanf( "%d", &today.hyear );
	printf( "月" ); scanf( "%d", &today.month );
	printf( "日" ); scanf( "%d", &today.day );
	printf( "曜日" ); 
	for( i = 0; i < 20 - 1; i++ ){
		c = getchar();
		if( c == EOF || c == '\n' ) break;
		d[ i ] = c;
	}
	d[ i ] = '\0';
	strcpy( today.day_of_week, d );
	
	print_day2( today );
	
	return 0;
}

void print_day2( struct date_t today )
{
	printf( "今日は,西暦%d 年(平成%d 年)%d 月%d 日 ( %s )です." , today.year, today.hyear, today.month, today.day, today.day_of_week );
}
	

Re: 構造体を用いて表示させる

Posted: 2016年1月06日(水) 21:15
by かずま
printf の書式で、全角の「%」を半角の "%" にしてください。

入力が「2015 Enter 28 Enter 1 Enter 6 wed Enter」だった場合、標準入力のバッファには
"2015\n28\n1\n6\nwed\n" が入ります。
最初の scanf("%d", &today.year); は "2015" を読み込みます。
次の scanf("%d", &today.hyear); は "\n28" を読み込みます。
次の scanf("%d", &today.month); は "\n1" を読み込みます。
次の scanf("%d", &today.day); は "\n6" を読み込みます。
次の c = getchar(); で c には '\n' が入ります。さあ、どうしますか?

void print_day2(const struct date_t *p)
にして、today.year の代わりに p->year などとしたほうが良いと思います。
もちろん、呼び出しは、print_day2(&today);

Re: 構造体を用いて表示させる

Posted: 2016年1月06日(水) 21:25
by かずま
かずま さんが書きました: 入力が「2015 Enter 28 Enter 1 Enter 6 wed Enter」だった場合、標準入力のバッファには
また、間違えた。
6 と wed の間も Enter です。

scanf("%19s", today.day_of_week); にしないのはなぜですか?

Re: 構造体を用いて表示させる

Posted: 2016年1月06日(水) 23:56
by box
KTN19 さんが書きました:入力したものを構造体に格納して、それをまとめて出力するというものなのですが、うまくできません。。。
まあ何はともあれ、「うまくできない」というのがどううまくいかないのかを具体的に書くことから始めるのが本筋でありましょう。

コンパイルをしたときにこんなエラーメッセージが出てコンパイルできない、とか、
コンパイルは通って実行ファイルはできたけど、いざ実行してみると
こんな入力をしたときにこんな出力結果を予想していたのだけれど、意に反してこんな結果を出力してしまった、という具合に、
「何をしたときにどうなったか」を示してください。
話はそこからです。

Re: 構造体を用いて表示させる

Posted: 2016年1月07日(木) 00:40
by KTN19
返信ありがとうございます!全角になってたんですね、エラーメッセージが分からなく気づきませんでした!助かりました!!
かずま さんが書きました: "2015\n28\n1\n6\nwed\n" が入ります。
最初の scanf("%d", &today.year); は "2015" を読み込みます。
次の scanf("%d", &today.hyear); は "\n28" を読み込みます。
次の scanf("%d", &today.month); は "\n1" を読み込みます。
次の scanf("%d", &today.day); は "\n6" を読み込みます。
次の c = getchar(); で c には '\n' が入ります。さあ、どうしますか?
'\n'の処理をどのようにするのが正解なのでしょうか?考えとしては、どうにか'\n'を無視して格納できるというものが思いついてしまっていい答えが見つからないのです。

boxさん、大変失礼いたしました。
コンパイルエラーメッセージがよく分からなく質問にしづらく曖昧な返しになってしまいました

Re: 構造体を用いて表示させる

Posted: 2016年1月07日(木) 01:20
by かずま
KTN19 さんが書きました: '\n'の処理をどのようにするのが正解なのでしょうか?考えとしては、どうにか'\n'を無視して格納できるというものが思いついてしまっていい答えが見つからないのです。
'\n' を無視するものを思いついたのなら、それがいい答えだと思うんですが、
それをここに書いてもらわないと、本当にいいか悪いかは判断できません。

No.3 で、「scanf("%19s", today.day_of_week); にしないのはなぜですか?」と
尋ねたんですが、それには答えてくれないのですか?
これ、いい答えと思いませんか?

最初は、「scanf("%s", today.day_of_week); にしないのはなぜですか?」
と尋ねようとしたんですが、
「バッファオーバーランしないように for文を使って 1文字ずつの入力にしました。」
という回答を予想して、19 を付けました。
KTN19 さんが書きました: コンパイルエラーメッセージがよく分からなく質問にしづらく曖昧な返しになってしまいました
どんなエラーメッセージですか?
解答する人が同じコンパイラを使っているとは限りません。
そのエラーメッセージをなぜここに書かないのですか?

とにかく、質問は具体的に、そして、すべての情報を包み隠さず出しましょう。

Re: 構造体を用いて表示させる

Posted: 2016年1月07日(木) 06:41
by KTN19
確かにいい答えであると思います。バッファオーバーランも考慮したscanfの書き方を知りませんでしたので、感嘆してました。

'\n'を無視するという答えがわからないではなく、無視するまでの過程の書き方が思いつかないの間違いです、失礼いたしました。


-------------------------------------------------------------------------------------------------
T11_3.c:40:107: warning: format specifies type 'char *' but the
argument has type 'int' [-Wformat]
...年)%d 月%d 日 ( %s )です." , today.year, today.hyear, tod...
~~ ^~~~~~~~~~~
%d
T11_3.c:40:120: warning: data argument not used by format string
[-Wformat-extra-args]
..."今日は,西暦%d 年(平成%d 年)%d 月%d 日 ( %s )です." , today.year, today.hyear, t...
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~


intを使っているつもりがchar *とエラーが出でいるため、この意味が分からなく苦悩してました。

Re: 構造体を用いて表示させる

Posted: 2016年1月07日(木) 22:21
by みけCAT
KTN19 さんが書きました:intを使っているつもりがchar *とエラーが出でいるため、この意味が分からなく苦悩してました。
まず、ここには警告しか書かれておらず、エラーはありません。
エラーが出ているなら、それを貼り付けてください。

そして、書式%sはメッセージの通りchar *型のデータを要求します。
%s用に渡すデータとしてintを使ってはいけません。