C言語で13日の金曜日を求めたい

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

C言語で13日の金曜日を求めたい

#1

投稿記事 by nassangogo » 7年前

初めて質問するので、テンプレートを使わさせていただきます。

[1] 質問文
 [1.1] 2001年から2100年にある13日の金曜日を全て求め、表示したいのです
 [1.2] 明日までの宿題なので数日前からじっくり組み立てました。
しかし、どうしてもうまくいかないで行き詰まってます。
先程yahoo知恵袋を使って質問したが、その通りにやっても上手に行かなかたです。
http://detail.chiebukuro.yahoo.co.jp/qa ... 4108524104
さっきからmacのターミナルを使って実行してみても、コンパイルの時点で行き詰まっています。

コード:

 
#include <stdio.h>

int main()
{
    int y,m,d,h,y1,m2;
    y=2001;
    m=1;
    d=13;
    y1=2001;
    m2=1;
    
while (y1<2100){
while (m2<12){
    if(m < 3){
        y=y-1;
        m=m+12;
    }
    h = (y + y/4 - y/100 + y/400 + (13 * m + 8)/5 + d)%7;
    if (h=5){
            printf ("%d %d %d",y,m,d);
            }
    m2=m+1;
    }
    y1=y+1;
  }
    return 0;
}
 

 [1.3] gcc ちぇーんそーのひ.c
ちぇーんそーのひ.c: In function ‘main’:
ちぇーんそーのひ.c:33: error: stray ‘\343’ in program
ちぇーんそーのひ.c:33: error: stray ‘\200’ in program
ちぇーんそーのひ.c:33: error: stray ‘\200’ in program
ちぇーんそーのひ.c:33: error: stray ‘\343’ in program
ちぇーんそーのひ.c:33: error: stray ‘\200’ in program
ちぇーんそーのひ.c:33: error: stray ‘\200’ in program
nakamotos-MacBook-Air:てすと tomoko$
なお、ソースコードは最初のメモ8行を省略しているので、エラーを起しているのは、元のソースコードで33行目のreturn 0では無いかと睨んでいる。

 [1.4] どうしたら自分が動かしたいように動くようになるのか教えてください。
どうソースコードを改変したら動くようになるのかよく分からないのです。
何故エラーになるのかよく分からず困っています。

[2] 環境  
 [2.1] OS :MACOS
 [2.2] コンパイラ名 :macのterminal

[3] その他
 ・どの程度C言語を理解しているか
授業で今年4月に初めて触れた
今までループや実数の扱い方などを習った
 ・Xcodeを使って書いた

どうかよろしくお願いします。

かずま

Re: C言語で13日の金曜日を求めたい

#2

投稿記事 by かずま » 7年前

nassangogo さんが書きました: ちぇーんそーのひ.c:33: error: stray ‘\343’ in program
"error: stray ‘\343’ in program" で検索してみましたか?

アバター
あたっしゅ
記事: 334
登録日時: 10年前
住所: 東京23区
連絡を取る:

Re: C言語で13日の金曜日を求めたい

#3

投稿記事 by あたっしゅ » 7年前

こういうのは、全角空白が入っているぽいよな、と思いつつ、
"error: stray ‘\343’ in program" で検索してみたら、
やっぱり、全角空白が入っているせいらしい。
手提鞄あたっしゅ、[MrAtassyu] http://ameblo.jp/mratassyu/
手提鞄屋魚有店(てさげかばんやうおありてん)
レスがついていないものを優先して、レスしています。時々、見当外れなレスをします。

nassangogo

Re: C言語で13日の金曜日を求めたい

#4

投稿記事 by nassangogo » 7年前

勉強不足ですみませんでした。
今検索した所、変な空白が入り込んでいるようですね。

空白を消した所、やっとコンパイルが通りました。
しかし、実行されても何も表示されません・・・。
何所がおかしいのでしょうかね…。

初級者
記事: 200
登録日時: 9年前

Re: C言語で13日の金曜日を求めたい

#5

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

20行目で h に 5 を代入しています。
それは意図どおりでしょうか?

トントン
記事: 100
登録日時: 10年前

Re: C言語で13日の金曜日を求めたい

#6

投稿記事 by トントン » 7年前

nassangogo さんが書きました:勉強不足ですみませんでした。
今検索した所、変な空白が入り込んでいるようですね。

空白を消した所、やっとコンパイルが通りました。
しかし、実行されても何も表示されません・・・。
何所がおかしいのでしょうかね…。
まず、インデントを揃えましょう。

解決方法として、
printf関数に渡すもの間違っていなければ
条件を確認していきます。

printf関数を呼び出す直前のif分の条件は成り立つのか。
1つ目のwhile文にはそもそも入っているのか。
2つ目のwhile文にはそもそも入っているのか。

条件の前後にprintf関数を埋め込むなり、
デバッガを使えるのであればブレークポイント張ってステップ実行すれば確認できると思います。

box
記事: 1751
登録日時: 9年前

Re: C言語で13日の金曜日を求めたい

#7

投稿記事 by box » 7年前

他の回答者さんからもありましたが、せめてこのくらいの字下げはできないものでしょうか。
字下げがきたないと見る気が失せますし、ミスを見つけにくくなると思います。
なお、下記はあくまで私の流儀です。何も押しつけようとしているわけではありません。

コード:

#include <stdio.h>
 
int main()
{
    int y, m, d, h, y1, m2;
    
    y = 2001;
    m = 1;
    d = 13;
    y1 = 2001;
    m2 = 1;
    
    while (y1 < 2100) {
        while (m2 < 12) {
            if (m < 3) {
                y = y - 1;
                m = m + 12;
            }
            h = (y + y/4 - y/100 + y/400 + (13 * m + 8)/5 + d) % 7;
            if (h = 5) {
                printf("%d %d %d", y, m, d);
            }
            m2 = m + 1;
        }
        y1 = y + 1;
    }
    return 0;
}
バグのないプログラムはない。
プログラムは思ったとおりには動かない。書いたとおりに動く。

nassangogo

Re: C言語で13日の金曜日を求めたい

#8

投稿記事 by nassangogo » 7年前

すみません。
非常に自分の勉強不足を自覚してます。
字下げすると非常に見易くなりますね。


hに代入しているのは、自分の意思通りです。
hでツエラーの定理を使って曜日が何であるかを求めています。
hはツエラーの定理の答えを入れるために作った代数です。

box
記事: 1751
登録日時: 9年前

Re: C言語で13日の金曜日を求めたい

#9

投稿記事 by box » 7年前

nassangogo さんが書きました: hに代入しているのは、自分の意思通りです。
問題となっているのは、20行目の
if文の中で

コード:

    if (h = 5)
と書いているのが本当に意図どおりですか?ということです。
本当は、hと5とが「等しいかどうか比較したい」のではありませんか?
その場合、等号は1個でいいんでしょうか?
バグのないプログラムはない。
プログラムは思ったとおりには動かない。書いたとおりに動く。

超絶右留斗羅天才プログラマー
記事: 44
登録日時: 7年前

Re: C言語で13日の金曜日を求めたい

#10

投稿記事 by 超絶右留斗羅天才プログラマー » 7年前

ツエラーの法則を使わず、全探索のアルゴリズムを用いてプログラムを作成してみました。ツエラーの法則を使うより重いですが、もしよろしければ参考にしてください(^^♪

コード:

#include <stdio.h>
int main()
{
    // 12ヶ月分の日数
    int m_max[12] = {31,28,31,30,31,30,31,31,30,31,30,31};
    int w = 0;      // 0なら月曜日
 
    // 100年分
    for( int y = 2001; y <= 2100; y++ ){
        // 閏年なら2月は29日
        if( y % 4 == 0 )
            m_max[1] = 29;
        // 閏年でないなら2月は28日
        else
            m_max[1] = 28;
 
        // 12ヶ月分
        for( int m = 0; m < 12; m++ ){
            // 日数分
            for( int d = 0; d < m_max[m]; d++ ){
                // 13日の金曜日ならカウント
                if( d == 12 && w == 4 ){
					printf("%d年%2d月%2d日(金)\n",y,m+1,d+1);
                }
                // 曜日補正
                w++;
                if(w==7)w=0;
            }
        }
    }
    // 入力待ち
    rewind(stdin);
    getchar();
    return 0;
}
課題が「ツエラーの法則を必ず使うことでしたらすみません(ノ_・;)

(2013/6/9/23:43 文章を一部訂正しました)
ただの超絶右留斗羅天才プログラマーです。同人ゲーム制作進捗度:7%

トントン
記事: 100
登録日時: 10年前

Re: C言語で13日の金曜日を求めたい

#11

投稿記事 by トントン » 7年前

nassangogo さんが書きました:勉強不足ですみませんでした。
今検索した所、変な空白が入り込んでいるようですね。

空白を消した所、やっとコンパイルが通りました。
しかし、実行されても何も表示されません・・・。
何所がおかしいのでしょうかね…。
とりあえず、最新のコードと現在の状況が知りたいですね。
初級者さん、boxさんが指摘されてる「if (h=5)」が解決できたとしても
そもそも、「実行されても何も表示されません」というのは
確認したソースの条件からはありえないわけで。。。

かずま

Re: C言語で13日の金曜日を求めたい

#12

投稿記事 by かずま » 7年前

トントン さんが書きました: 初級者さん、boxさんが指摘されてる「if (h=5)」が解決できたとしても
そもそも、「実行されても何も表示されません」というのは
確認したソースの条件からはありえないわけで。。。
本当ですか?

元のソースから、全角スペースを除去すると、コンパイルできるように
なります。if (h=5){ のままのものを、
VC++ でコンパイルして実行した場合は 2000 13 13 と表示されますが、
gcc でコンパイルした場合は、出力が行バッファリングされるので
改行のない 2000 13 13 は表示されません。

if (h==5){ に修正さればものは、VC++ であろうと、gcc であろうと、
y = 2000, m = 13 のまま無限ループになるので、何も表示されません。

「実行されても何も表示されません」というのは
確認したソースの条件からはありえるわけです。

トントン
記事: 100
登録日時: 10年前

Re: C言語で13日の金曜日を求めたい

#13

投稿記事 by トントン » 7年前

かずま さんが書きました:
トントン さんが書きました: 初級者さん、boxさんが指摘されてる「if (h=5)」が解決できたとしても
そもそも、「実行されても何も表示されません」というのは
確認したソースの条件からはありえないわけで。。。
本当ですか?

元のソースから、全角スペースを除去すると、コンパイルできるように
なります。if (h=5){ のままのものを、
VC++ でコンパイルして実行した場合は 2000 13 13 と表示されますが、
gcc でコンパイルした場合は、出力が行バッファリングされるので
改行のない 2000 13 13 は表示されません。

if (h==5){ に修正さればものは、VC++ であろうと、gcc であろうと、
y = 2000, m = 13 のまま無限ループになるので、何も表示されません。

「実行されても何も表示されません」というのは
確認したソースの条件からはありえるわけです。
1.ありえないわけで
→調べました。なるほどです。
訂正、ありえます。

2.if (h==5){ に修正
→ごめんなさい。こちらはミスですね。
仰るとおりの状態になりますね。

nassangogo

Re: C言語で13日の金曜日を求めたい

#14

投稿記事 by nassangogo » 7年前

宿題はヘロンの定理のプログラムを作った上で、
そのプログラムを少し改変してプログラムを組もうという宿題です。
それに私も何故動かないのか疑問なので、提出期限の夕方まで少し頑張ってみようと思います。

コード:

#include <stdio.h>

int main()
{
    int y, m, d, h, y1, m2;
    
    y = 2001;
    m = 1;
    d = 13;
    y1 = 2001;
    m2 = 1;
    
    while (y1 < 2100) {
        while (m2 < 12) {
            y=y+1;
            m=m+1;
            if (m < 3) {
                y=y-1;
                m=m+12;
            }
            h=(y+y/4-y/100+y/400+(13*m+8)/5+d)%7;
            if (h==5) {
                printf("%d%d%d",y,m,d);
            }
            m2=m+1;
        }
        y1=y+1;
    }
    return 0;
}
にしてみましたが、何も表示されません・・・。
どうしてなのでしょうか?

non
記事: 1097
登録日時: 9年前

Re: C言語で13日の金曜日を求めたい

#15

投稿記事 by non » 7年前

yとy1、mとm1の使い方が明確でないようです。もう一度整理してみてはどうでしょうか。
また、内側のwhile(m2<12)を抜けたら、m2はまた1月から始めなくては。
non

novelmaniagogo

Re: C言語で13日の金曜日を求めたい

#16

投稿記事 by novelmaniagogo » 7年前

本当ですね・・・。
これじゃあ、明らかにおかしいですね・・・。

コード:


#include <stdio.h>

int main()
{
    int y, m, d, h, y1, m2;
    
    y = 2001;
    m = 1;
    d = 13;
    y1 = 2001;
    m2 = 1;
    
    while (y1 < 2100) {
        while (m2 < 12) {
            y=y+1;
            m=m+1;
            if (m < 3) {
                y=y-1;
                m=m+12;
            }
            h=(y+y/4-y/100+y/400+(13*m+8)/5+d)%7;
            if (h==5) {
                printf("%d%d%d",y1,m2,d);
            }
            m2=m+1;
        }
        y1=y+1;
    }
    return 0;
}
にしてみました。
今一生懸命文字が何も出力されない理由を探してます。

YuO
記事: 942
登録日時: 9年前
住所: 東京都世田谷区

Re: C言語で13日の金曜日を求めたい

#17

投稿記事 by YuO » 7年前

xcodeとかのデバッガ使って追った方が楽なのですが……。
terminalとのことなので,とりあえずprintfデバッグを。

whileの開始直後や終了直前,ifの前や後などに,printfで変数の内容を出力してみて下さい。
例えば,14行目の直後には

コード:

printf("while(1).begin : y=%d, m=%d, d=%d, y1=%d, m2=%d", y, m, d, y1, m2);
23行目の直後には

コード:

printf("if(2).before : y=%d, m=%d, d=%d, h=%d, y1=%d, m2=%d", y, m, d, h, y1, m2);
のように,どこで出力したかもわかるように書いておきます。
最初は100年分ではなく,5年分とかでやってみるとよいでしょう。
あとは,結果を見て,想定した値になっているかを検証します。
恐らく,想定した値にはなっていないはずなので,その理由を考えてバグを潰していくのがよいでしょう。

# 一番の元凶は,forでなくwhileを使ったことだと思いますが……。

novelmaniagogo

Re: C言語で13日の金曜日を求めたい

#18

投稿記事 by novelmaniagogo » 7年前

コード:

#include <stdio.h>

int main()
{
    int y, m, d, h, y1, m2;
    d = 13;
    for (y=2001; y<2002;y++){
        y1=y;
        for(m=1;m<13;m++){
            m2=m;
            if (m<3){
                y=y-1;
                m=m+12;
            }
            h=(y+y/4-y/100+y/400+(13*m+8)/5+d)%7;
            if (h==5){
                printf(y,y1,m2);
            }
        }
    }
    return 0;
}
先程のアドバイスを踏まえて変更してみました。
そして上でおっしゃられた確認用の文を入れた所、確認用の数字が沢山出力されました。
恐らく条件文の所がおかしいのだと思います。
if (h==5){
printf(y,y1,m2);
のところが。
少し頑張ってみようと思います

non
記事: 1097
登録日時: 9年前

Re: C言語で13日の金曜日を求めたい

#19

投稿記事 by non » 7年前

non さんが書きました:yとy1、mとm1の使い方が明確でないようです。もう一度整理してみてはどうでしょうか。
まだ、明確でないことが原因です。
non

YuO
記事: 942
登録日時: 9年前
住所: 東京都世田谷区

Re: C言語で13日の金曜日を求めたい

#20

投稿記事 by YuO » 7年前

ループ変数の値をループ中で変更してはいけません。
これは絶対ではないですが,理由なくやることは今回のようにバグの元になります。

出力された値をよく見れば,yに関するループの先頭でyの値が2001から変化していないことがわかるはずです。
また,mに関するループの末端でmの値が常に13であることもわかるはずです。

novelmaniagogo

Re: C言語で13日の金曜日を求めたい

#21

投稿記事 by novelmaniagogo » 7年前

コード:

#include <stdio.h>

int main()
{
    int y, m, d, h, o, p;
    d = 13;
    for (y=2001; y<2100;y++){
        o=y;
        for(m=1;m<13;m++){
            p=m;
            if (m<3){
                o=y-1;
                p=m+12;
            }
            h=(o+o/4-o/100+o/400+((13*p+8)/5)+d)%7;
            if (h==5){
                printf("%d/%d/%d/",y,m,d);
         }
        }
    }
}
にしたらちゃんと表示されるようになりました。
ありがとう御座いました

non
記事: 1097
登録日時: 9年前

Re: C言語で13日の金曜日を求めたい

#22

投稿記事 by non » 7年前

あってる気がしないなぁ。カレンダで確認してみた?
non

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

Re: C言語で13日の金曜日を求めたい

#23

投稿記事 by みけCAT » 7年前

ここにカレンダーがあります。
http://www5a.biglobe.ne.jp/%257eaccent/kazeno/calendar/
複雑な問題?マシンの性能を上げてOpenMPで殴ればいい!(死亡フラグ)

かずま

Re: C言語で13日の金曜日を求めたい

#24

投稿記事 by かずま » 7年前

o=y; を p=m; の直前に持ってくるといいですね。

おまけ

コード:

#include <stdio.h>

int dow(int y, int m, int d)   // day of week
{
    return y -= m<3, (y + y/4 - y/100 + y/400 + "([^]=*-/+_)%."[m] + d) % 7;
}

int main(void)
{
    int y, m;
    for (y = 2001; y <= 2100; y++)
        for (m = 1; m <= 12; m++)
            if (dow(y, m, 13) == 5)
                printf("%d/%2d/13\n", y, m);
    return 0;
}
文字コードに依存するようなこんなコードを書いてはいけません。

閉鎖

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