閏年の判別

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

閏年の判別

#1

投稿記事 by 釣り師 » 15年前

先日質問した日付の経過計算なんですが、まずは閏年の計算が出来るようにしたいと思い、色々なサイトをみて調べ、とりあえず書いてみました。

#include "DxLib.h"
#include <stdio.h>
#include <windows.h>

int WINAPI WinMain(HINSTANCE hInstance , HINSTANCE hPrevInstance , PSTR lpCmdLine , int nCmdShow ) {


SetGraphMode( 250, 100, 16);
ChangeWindowMode(TRUE); //ウィンドウモードに変更する為の関数
SetWindowStyleMode(6);
DxLib_Init(); //DXライブラリの初期化
SetAlwaysRunFlag(TRUE);
SetDrawScreen(DX_SCREEN_BACK); //描画先を裏画面に変更(13章参照)

int White = GetColor( 255,255,255 );

while( CheckHitKey(KEY_INPUT_SPACE)==0 ){

GetDateTime( &Date );
ProcessMessage();
ClearDrawScreen();

int year = KeyInputNumber( 0 , 16 , 9999 , 1000 , FALSE ) ;

if( year %100 == 0 )
{
if( year %400 == 0 )
DrawFormatString( 0,0, White,"%d年は閏年です。" ,year );
else
DrawFormatString( 0,0, White, "%d年は閏年ではありません。", year );
}
else
{
if( year %4 == 0)
DrawFormatString( 0,0, White, "%d年は閏年です。",year);
else
DrawFormatString( 0,0, White, "%d年は閏年ではありません。",year);
}

ScreenFlip();
}
DxLib_End();
return 0;
}



見にくかったらすみません。
まずKeyInputNumber( 0 , 16 , 9999 , 1000 , FALSE ) ;で西暦年を入力し、計算に従い閏年か否かを判別するプログラムなんですが。
判別はうまく出来るんですが、一回動かしてもらえるとわかるとおり、閏年かどうかのコメントが表示された瞬間、消えてしまいます。
さらに、Escキーを押しても終了させることができません。
何故でしょうか?わかる方お願いします。

VisualC++ 2010
DxLibを使っています。


タイトル着け忘れました。
画像

fatens

Re:閏年の判別

#2

投稿記事 by fatens » 15年前

>閏年かどうかのコメントが表示された瞬間、消えてしまいます。

表示した次のフレームで ClearDrawScreen() によって消されるからです。


>Escキーを押しても終了させることができません。

while( CheckHitKey(KEY_INPUT_SPACE)==0 )
↑スペースキーを押すと終了するようにしてありますが...

初級者

Re:閏年の判別

#3

投稿記事 by 初級者 » 15年前

そのif文は、もっと簡単に書けます。

西暦年が、
「4で割り切れて100で割り切れない」
または
「400で割り切れる」
とき、うるう年
そうでないとき、平年

ナムアニクラウド

Re:閏年の判別

#4

投稿記事 by ナムアニクラウド » 15年前

回答させていただきます。よろしくお願いします。

このプログラムでは、「××年は閏年…」の文字列を消した後、もう一度西暦年を入力させるようにしています。
これはKeyInputNumberがwhileの中にあることが原因です。
KeyInputNumberがwhileの中にあるということは、西暦年の入力を何度も要求しているということなのです。

ESCで終了できない問題は、fatensさんのおっしゃるとおり
while( CheckHitKey( KEY_INPUT_SPACE )==0 )
となっていることが原因です。

以下は、問題のソースからバグを取り除いたものです。

<hr>
#include "DxLib.h"
#include <stdio.h>
#include <windows.h>  

int WINAPI WinMain(HINSTANCE hInstance , HINSTANCE hPrevInstance , PSTR lpCmdLine , int nCmdShow ) {

    SetGraphMode( 250, 100, 16);
    ChangeWindowMode(TRUE);           //ウィンドウモードに変更する為の関数
    SetWindowStyleMode(6);
    DxLib_Init();                     //DXライブラリの初期化
    SetAlwaysRunFlag(TRUE);
    SetDrawScreen(DX_SCREEN_BACK);    //描画先を裏画面に変更(13章参照)

    int White = GetColor( 255,255,255 );

    int year = KeyInputNumber( 0 , 16 , 9999 , 1000 , FALSE ) ;

    while( CheckHitKey( KEY_INPUT_ESCAPE )==0 ){

        //不要なGetDateTimeを削除
        ProcessMessage();
        ClearDrawScreen();

        if( year %100 == 0 )
        {
            if( year %400 == 0 )
                DrawFormatString( 0,0, White,"%d年は閏年です。" ,year );
            else
                DrawFormatString( 0,0, White, "%d年は閏年ではありません。", year );
        }
        else
        {
            if( year %4 == 0)
                DrawFormatString( 0,0, White, "%d年は閏年です。",year);
            else
                DrawFormatString( 0,0, White, "%d年は閏年ではありません。",year);
        }

        ScreenFlip();
    }
    DxLib_End();
    return 0;
}
これをコピペでとりあえず動くはずです。
読んでくれてありがとうございます。


ここから余談なので見てくれなくても大丈夫です。

DXライブラリのリファレンスなどを見ていただくと分かりますが、このソースに登場する二つの関数
DxLib_Init();
ProcessMessage();
は、失敗して-1を返したときに、プログラムを即時に終了する必要があります。
今回のソースでは-1を返した時の処理などはしませんでした(大幅改変すると分かりづらいので)。
DXライブラリを用いた実際のプログラミングでは、この二つの関数のことを忘れないようにしましょう。

では、ここまで読んでくれてありがとうございました。

釣り師

Re:閏年の判別

#5

投稿記事 by 釣り師 » 15年前

fatensさん。
 すみません。
 Escとスペースを間違えました。
 Escで終了するようにしても終了できなかったので、スペースで試したのですが、やはりダメでした。
 こちらの表記ミスでした。

初級者さん。
 if文の中身は
 (year%4 == 0 && year%100 != 0 || year%400 == 0)
 こんな感じですね!

ナムアニクラウドさん。
 丁寧にありがとうございます。大丈夫でした!が、

while( CheckHitKey( KEY_INPUT_ESCAPE )==0 ){

int year = KeyInputNumber( 0 , 16 , 9999 , 1000 , FALSE ) ;

while( CheckHitKey( KEY_INPUT_SPACE )==0 ){

//不要なGetDateTimeを削除
ProcessMessage();
ClearDrawScreen();

if( year %100 == 0 )
{

と、判定結果表示後にスペースを押すと、再度入力できて、その入力画面でEscを押すと終了できるようにしたいのですが…。なぜかEscを押しても終了してくれません。

シエル

Re:閏年の判別

#6

投稿記事 by シエル » 15年前

KeyInputNumberが何の関数かは知りませんが、こいつで止まっているからでしょう。

釣り師

Re:閏年の判別

#7

投稿記事 by 釣り師 » 15年前

よくわかりませんが、スペースとEsc、当時に押したら解決しました!ありがとうございました!

ナムアニクラウド

Re:閏年の判別

#8

投稿記事 by ナムアニクラウド » 15年前

解決はしたようですが、疑問が残るようなので説明しましょう。
宜しければ一読を。

KeyInputNumberを呼ぶと、その処理が終わるまで他の処理は止まってしまいます。
するとwhileの条件判定は、数値入力が完了するまで行われません。
つまりKeyInputNumberの処理中にEscを押しても終了しないわけです。
while( CheckHitKey( KEY_INPUT_ESCAPE )==0 )
{
    int year = KeyInputNumber( 0 , 16 , 9999 , 1000 , FALSE ) ;    //ここで停止
}
KeyInputNumber関数は最後の引数に TRUE を指定すると、Escキーにより入力がキャンセル可能で、
キャンセルされた場合 入力可能な最大値 + 1 の値(ここでは10000)が返されます。
これを用いて終了判定をすればいいと思われます。
読んでくれてありがとうございました。

閉鎖

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