• ベストアンサー

ループが1回で終わってしまいます。

ファイルから文字列を一行ずつ読み込んで、文字列内の整数を比較してMIDI出力するようにしてるのですが、ループが一回で終わってしまっているらしく、ファイル内の文字列の初めの行しか読み込めていません。どこがおかしいのか自分では分からないので、わかる方教えてください! ちなみに、Visual C++ 2008 Express Edition、Win32APIです。 以下が問題のソースです。 while(_fgetts(buf, 30, fp)){ if(feof(fp)){ break; }else{ _tcstok(buf, TEXT("\n")); _stscanf(buf, _T("- { x:%d, y:%d }"), &m, &n); if(n<200){ if((m>=0 && m<110)){ midiOutShortMsg(hMidOut , MIDIMSG(0x90 , 0x48 , 40)); return 0; }else if((m>=110 && m<220)){ midiOutShortMsg(hMidOut , MIDIMSG(0x90 , 0x50 , 40)); return 0; }else if((m>=220 && m<330)){ midiOutShortMsg(hMidOut , MIDIMSG(0x90 , 0x52 , 40)); return 0; }else if((m>=330 && m<440)){ midiOutShortMsg(hMidOut , MIDIMSG(0x90 , 0x53 , 40)); return 0; }else if((m>=440 && m<550)){ midiOutShortMsg(hMidOut , MIDIMSG(0x90 , 0x55 , 40)); return 0; }else if((m>=550 && m<660)){ midiOutShortMsg(hMidOut , MIDIMSG(0x90 , 0x57 , 40)); return 0; }else if((m>=660 && m<770)){ midiOutShortMsg(hMidOut , MIDIMSG(0x90 , 0x59 , 40)); return 0; }else{ break; } }else if(n>=200 && n<400){ if((m>=0 && m<110)){ midiOutShortMsg(hMidOut , MIDIMSG(0x90 , 0x36 , 40)); return 0; }else if((m>=110 && m<220)){ midiOutShortMsg(hMidOut , MIDIMSG(0x90 , 0x38 , 40)); return 0; }else if((m>=220 && m<330)){ midiOutShortMsg(hMidOut , MIDIMSG(0x90 , 0x40 , 40)); return 0; }else if((m>=330 && m<440)){ midiOutShortMsg(hMidOut , MIDIMSG(0x90 , 0x41 , 40)); return 0; }else if((m>=440 && m<550)){ midiOutShortMsg(hMidOut , MIDIMSG(0x90 , 0x43 , 40)); return 0; }else if((m>=550 && m<660)){ midiOutShortMsg(hMidOut , MIDIMSG(0x90 , 0x45 , 40)); return 0; }else if((m>=660 && m<770)){ midiOutShortMsg(hMidOut , MIDIMSG(0x90 , 0x47 , 40)); return 0; }else{ break; } } } ファイルの中身 - { x:543, y:62 } - { x:561, y:177 } - { x:26, y:375 } - { x:265, y:220 } . . . です。

質問者が選んだベストアンサー

  • ベストアンサー
  • php504
  • ベストアンサー率42% (926/2160)
回答No.6

>単音を次々に流すようにするにはどうすればいいのでしょうか? 1行読むごとにSleep( )で時間を置いたらどうでしょう。 Sleep(1000); で約1秒待ちます。

m22015
質問者

お礼

やってみたら、考えていたような結果になりました!! ありがとうございます!

その他の回答 (5)

noname#88772
noname#88772
回答No.5

 こんにちは。  本来の解答ではありませんが今後の参考の為に...  ソースを見ていて if else の嵐で頭がこんがらがりそうになりました。 今のソースのままだと今回の問題を解決しても以下の問題が出てきます。  ・修正箇所の大量発生  ・修正忘れによるバグ発生  根本的な修正を行った方がいいと思います。  ソースを見た感じ、要は m と n の値によって midiOutShortMsg() に入れる中身が変わるってことですよね? なので m, n を入力したら midiOutShortMsg() に入れる値が返る関数 を一つ作ればいいと思います。それで上記の問題も解決すると思います。 もちろん、関数内も if, else の嵐では意味がありませんので簡単に 実現できる方法を考えてみましょう。  ご参考までに。

m22015
質問者

お礼

確かにそうですね・・・。 if elseの繰り返しはあまり良くないことは分かっているのですが、実装が簡単なので。勉強不足であり勉強中なんです(;_;) そのとおりです! ありがとうございます。やってみます!

noname#76085
noname#76085
回答No.4

No.1です。 申し訳ありません、トンチンカンな回答をしてしまいました。(真と偽の逆転)大変申し訳ありません。 他の回答者様の通り、return文がどういうものかを覚えましょう。

回答No.3

midiOutShortMsgを呼んだ直後に必ずreturn文がありますが、return文は何をする文かご存じでしょうか?

m22015
質問者

お礼

サンプルソースを見て何も考えずに midiOutShortMsg(.....); return 0; とそのまま書いてました(^_^;) 実際勉強不足なんで、教科書読んで見直します! ご指摘ありがとうございました。

  • php504
  • ベストアンサー率42% (926/2160)
回答No.2

return 0; でループを抜けているからではないでしょうか

m22015
質問者

お礼

ご指摘ありがとうございます。 return 0; を削除してみたところ、なぜか不協和音のように一度にMIDIが出力されるようになってしまいました。 単音を次々に流すようにするにはどうすればいいのでしょうか?

noname#76085
noname#76085
回答No.1

_fgettsの戻り値は確認していますか? whileの終了条件をもう一度思い出してみましょう。

m22015
質問者

お礼

回答ありがとうございます。 if(feof(fp)){ break; } で最後まで読みこんだらループを抜ける、で良いのかと考えていました。 もう一度確認してみます。

関連するQ&A

専門家に質問してみよう