• 締切済み

C++コンソールプログラムをBuilder6に書き直す

卒業研究に取り組んでおり、 コンソールプログラムで得た出力結果(.exe)を、BuilderのMemoで表示させたいのですが、どの部分を書き直したらいいのかわかりません。私が思うに 1.Wimmain 2.出力部分 を書き直せばいいのかなと思うのですが、参考になるサイトなど知っていたら、またアドバイス等ございましたら教えて下さるとありがたいです。 今、namespaceの次にmainを書いているのですが、  E2268 未定義の関数を呼び出した というエラーが表示され、main文は読み込めていないようです。どなたかわかる方いましたらアドバイス宜しくお願いします。 追伸 .exeの内容をShellExcuteで呼び出すということも可能なのでしょうか。宜しくお願いいたします。

みんなの回答

  • BLUEPIXY
  • ベストアンサー率50% (3003/5914)
回答No.9

>参考にできるサイトなどご存じであれば教えてほしいのですが… 参考になるサイトなんかないと思います。 というのも、ステップ実行のアルゴリズムというのは、アルゴリズムとして独立したようなものではないためです。 ステップ実行したいプログラムの構造に強く依存していて、その"ステップ"の切り出しはプログラムに依るからです。 強いて言うなら、ステップで実行できるような構造であらかじめ作っておくということでしょうか 例えば、このプログラムで言えば、その時の状態をゴールの状態に1コ変移させるというのが1つのステップ(ゴールを目指してということ、トラックバックは当然起こる)とするというとわかりがいいかもしれません。 ステップ実行というのを、どういうレベルで捉えるかでまた違うのかも知れませんが、 簡単には、今あるプログラムでは、whileの一回のループを1つのステップとして考えるなら、ボタンを押す毎にループ一回分の実行をすると考えれば、(今のループを開くことに相当する)いいのじゃないですか? まあ、好きにやればいいですよ。 もともとこのプログラムってどっかに載っていたものなんですよね。 一体あなたが考えたことってどれ程有るのでしょうか? すぐに、何かに求めるのではなく少しは試行錯誤しないと何も身に付きません。

makefile
質問者

お礼

依存してしまい、大変すみませんでした。 それでもお返事を下さり申し訳なく思います。 がんばります。

  • BLUEPIXY
  • ベストアンサー率50% (3003/5914)
回答No.8

>…の方が取り組みやすいですかね? いろいろちゃちゃを入れてごめんなさい 好きにやってもらえばいいんですよ。

makefile
質問者

お礼

こんなお返事させてすみません。 まったく見当の付かないもので思わずどちらが難しくないのかという意味で聞いてしまいました。 しかしながらステップ実行ですが、考え方がわからず… 参考にできるサイトなどご存じであれば教えてほしいのですが…

  • BLUEPIXY
  • ベストアンサー率50% (3003/5914)
回答No.7

>例えば、出力先としてMemoコンポーネントを引数で渡すようなプログラムにするとしても、State側とのインターフェース部分でやるようにするということです 確かに、変な文章ですね。すみません。 言いたかったことは、 利用するプログラムから #include "State.h"すれば使えるようにするということで、Stateの実現部分でMemo1とかMemo2とかを直接触るようなプログラムにはしないということです。 つまり、決められたインターフェースにしたがって、Stateは出力し、利用する側は出力を受けるようにするということです。 まあ、その受け渡し窓口は、Stringでも、strstreamでも、MemoでもMemo->Linesでもいいかと思いますけど。

makefile
質問者

お礼

お返事ありがとうございます。 >#include "State.h"すれば使えるようにするということで、Stateの実現部分でMemo1とかMemo2とかを直接触るようなプログラムにはしないということです。 の文章が理解に苦しみました。。 #5より >print_progress( s , open_list , closed_list ); >my::cout << endl; >の部分で、継続できるように作り直さないとしょうがないのじゃないでしょうか >簡単には、 >単に、メッセージボックスを表示して、継続するようにすればいいだけの様にも思えます。 継続するとはどういう意味でしょうか。 例えば今考えている例としては    1.Buttonを押すことにより1ステップずつ、1つのMemo実行結果が表示される  2.Buttonを押し、1ステップ結果が表示され、同時にMessageBoxを出し、Box内のButtonをクリックすると2ステップ目の結果が表示される だとすれば1.の方が取り組みやすいですかね? 別のmemoに表示するのは難しそうなので、まずは実行部分をいじろうかと思っているのですが…

  • BLUEPIXY
  • ベストアンサー率50% (3003/5914)
回答No.6

>Memo出力のところで止まってしまい どのように実現しようとしているかは知らないので、見当違いのコメントかもしれませんが、 struct Stateの問題点の1つは、 coutを使っていることです。 coutは、言わば大域変数で、struct Stateは、出力をこれに依存しています。 これでは、カプセル化されてるとは言えず、使い難いものになります。今回のような出力を他に切り替えようと言う場合に、苦労することになります。 なので、Stateを大幅に変更しようと考えておられるのなら、そのような、カプセル化ということを考えてみられると良いと思います。 例えば、今回は、coutを別のストリームで置き換えることで、ラップをかぶせて、元の部分がそのままでいけるようにしたわけですが、ストリームを、クラス変数のような形で、クラスに持たせることにし、コンストラクタにストリームの参照を渡すことで、簡単に切り替えることができたと思います。 現在は、外部の関数である、print_*の関数の引数で渡してもいいし。 最悪なのは、それぞれの部分でMemoコンポーネントに直接アクセスすることですが、 例えば、出力先としてMemoコンポーネントを引数で渡すようなプログラムにするとしても、State側とのインターフェース部分でやるようにするということです。 そうすれば、オーバーロードで、出力先が、ストリームの場合、Memoコンポーネントの場合というように入口を作ることができます。 なんだか、わけわからんコメントだとしたらすみません。 #5でのコメントが、coutを単にMemo->Lines->Addに置き換えるようなこと意味していると思われたらイヤなので余談を書いてみました。

makefile
質問者

お礼

お返事ありがとうございます。大幅に変更しなければ出力先を変えるのは難しいんですね、やはり。 いまの出力方法ではS,Open_listなど区別できないですもんね… 難しいお話でしたが理解はできました。(書くのは別問題ですが… ひとつ >例えば、出力先としてMemoコンポーネントを引数で渡すようなプログラムにするとしても、State側とのインターフェース部分でやるようにするということです。 の意味合いがよく取れなかったのですがもう少し説明して頂けませんでしょうか。

  • BLUEPIXY
  • ベストアンサー率50% (3003/5914)
回答No.5

>別のメモに表示するにはどのようにしたらいいのでしょうか #1の参考URLは、見ましたか? そもそも、coutしている部分を 参考URL#2 「Memo1->Lines->Add("書きたい文字列"); のようにして、メモに行を追加することができます。」 のようにして、メモに文字列を追加していくことができます。(同じことを言ってるにすぎませんが、やってみてから聞いてるんでしょうねと言いたいだけです) >結果をステップ実行で一探索ごと表示していくにはどのようにすればよいのでしょうか。 print_progress( s , open_list , closed_list ); my::cout << endl; の部分で、継続できるように作り直さないとしょうがないのじゃないでしょうか 簡単には、 単に、メッセージボックスを表示して、継続するようにすればいいだけの様にも思えます。 勘違いしてたらすみません。

  • BLUEPIXY
  • ベストアンサー率50% (3003/5914)
回答No.4

>main関数について main関数は、特別な関数で、コンソールプログラムの場合、初期起動プロセス(?)から呼び出されます。 Winmain関数は、ウインドウズプログラムで同等のもの(最初に呼び出される)と考えてもいいのですが、 デルファイやC++ビルダー(あるいはVB)のようなイベント駆動型のプログラムを書いている時には、あまり気にしないでよいものです。 結論から言うと、イベント処理関数の中にmain関数を書いてもしょうがないです。(特別な呼び出しをされる関数とかでもなんでもないので) イベント駆動型では、 例えば、ボタンをクリックしたら何々を実行するのようにプログラムを作成します。 なので、この場合、コンソールプログラムで実行したかったmainの中の処理部分を(ボタンを押すことで駆動されるように)書けばいいのです。 C++ビルダーに限らず、一般的にC系列の言語(GCCは除く)では、関数の中で関数を定義するということができません。 なので、ボタンイベントに今回のような全てのプログラムを書くのは正しくないです。 Stateは、プログラムというよりは、構造体なので、書けるかもしれませんが、こういう、クラスやC++でのクラスに準じた構造体は(再利用するだろうと思われるものは)別にするのが普通です。(ちなみに関数部分(structの外の部分)は、関数の中の関数になるのでできないと思います)

makefile
質問者

お礼

お返事遅くなり申し訳ありません。 細部にわたる説明、大変ありがとうございました。 ちなみにtesting、open_list、close_list、Resultをそれぞれ別のメモに表示するにはどのようにしたらいいのでしょうか。 私の案として、 print_progress1,2,3に分け、それぞれにs、open_list,closed_listの表示部分を書き、呼び出せばと思ったのですが、その後のMemo出力のところで止まってしまい… またこの結果をステップ実行で一探索ごと表示していくにはどのようにすればよいのでしょうか。 意見ばかり求めてしまい、大変申し訳ないです。すみません。

  • BLUEPIXY
  • ベストアンサー率50% (3003/5914)
回答No.3

基本的なアイデア、namespaceを利用し、coutへの出力をstrstreamのcoutに振り替える、そうした文字列をメモコンポーネントにセットする。 手順1:プログラムファイルをコピーし、拡張子をcppからhに変えてStateをプログラムからincludeできるようにする 手順2:coutをostrstream(文字列への出力ストリーム)に置き換える為にnamespaceを定義し、ostrstream coutを定義する 手順3:main関数部分を削除する 以上の処理をしたState.h #include <deque> #include <iostream> #include <strstream> using namespace std; namespace my{ ostrstream cout; struct State{ bool wolf; bool goat; bool cabbage; bool man; deque<State> path; State() : wolf( false ), goat( false ), cabbage( false ), man( false ), path(){ } bool succeeded() const{ return( this -> wolf && this -> goat && this -> cabbage && this -> man ); } bool failed() const { return( (wolf == goat && man != wolf)||(goat == cabbage && man != goat)); } State move_wolf() const { State s = *this; s.path.push_back( *this ); if ( s.wolf == s.man ){ s.wolf = !s.wolf; s.man = !s.man; } return( s ); } State move_goat() const { State s = *this; s.path.push_back( *this ); if ( s.goat == s.man ){ s.goat = !s.goat; s.man = !s.man; } return( s ); } State move_cabbage() const { State s = *this; s.path.push_back( *this ); if ( s.cabbage == s.man ) { s.cabbage = !s.cabbage; s.man = !s.man; } return( s ); } State move_man() const { State s = *this; s.path.push_back( *this ); s.man = !s.man; return( s ); } bool operator == ( const State& s ) const{ return( this->wolf == s.wolf && this->goat == s.goat && this->cabbage == s.cabbage && this->man == s.man ); } bool operator != ( const State& s ) const{ return(!(*this == s)); } }; ostream& operator << ( ostream & ostr , const State & s ){ ostr << (s.wolf ? "" : "w") << (s.goat ? "" : "g") << (s.cabbage ? "" : "c") << (s.man ? "" : "m") << "-" << (s.wolf ? "w" : "") << (s.goat ? "g" : "") << (s.cabbage ? "c" : "") << (s.man ? "m" : ""); return( ostr ); } void print_progress( const State& s, const deque<State>& open_list, const deque<State>& closed_list){ cout << "Testing " << s << endl; cout << "Open List ="; for ( size_t i = 0 ; i < open_list.size() ; i ++ ){ cout << " " << open_list[i]; } cout << endl; cout << "Closed List ="; for ( size_t i = 0 ; i < closed_list.size() ; i ++ ){ cout << " " << closed_list[i]; } cout << endl; } void print_result( const State & s ){ cout << "Result = "; for ( size_t i = 0 ; i < s.path.size() ; i ++ ){ cout << s.path[i] << " "; } cout << s << endl; } } //namespace my; 手順4:C++ビルダーを立ち上げて、メモコンポーネントとボタンコンポーネントを配置する 手順5:メモは初期文字列を消して、スクロールできるようにしておく、ボタンは名前を変える。 手順6:プロジェクト及びユニットを名前を付けて保存する 手順7:作成しておいたState.hを、作成したプロジェクトフォルダにコピーする 手順8:フォーム上のボタンをクリックしてボタンクリックイベントを作成する 手順9:元のプログラムのmain関数の中身をココにコピー&ペーストする 手順10: return 文は消す。 coutの部分はmy::coutに変更しMemo1->Textに代入する Memo1では、\nを\r\nに変更しないといけないのでAnsiReplaceStrする State.hとvcl\StrUtils.hppをincludeするように書く namespace my を使えるようにしておく 以上を処理したUnit1.cpp(このまま使わないでIDE上で書くこと) //--------------------------------------------------------------------------- #include <vcl.h> #pragma hdrstop #include "Unit1.h" #include <vcl\StrUtils.hpp> //--------------------------------------------------------------------------- #pragma package(smart_init) #pragma resource "*.dfm" #include "State.h" using namespace my; TForm1 *Form1; //--------------------------------------------------------------------------- __fastcall TForm1::TForm1(TComponent* Owner) : TForm(Owner) { } //--------------------------------------------------------------------------- void __fastcall TForm1::Button1Click(TObject *Sender) { State start_state; deque<State> open_list; deque<State> closed_list; open_list.push_back( start_state ); while( ! open_list.empty() ){ State s = open_list.front(); open_list.erase( open_list.begin() ); print_progress( s , open_list , closed_list ); my::cout << endl; if ( s.succeeded() ){ print_result( s ); break; } if ( s.failed() ){ continue; } if ( find( closed_list.begin() , closed_list.end() , s )== closed_list.end() ){ open_list.push_back( s.move_wolf() ); open_list.push_back( s.move_goat() ); open_list.push_back( s.move_cabbage() ); open_list.push_back( s.move_man() ); closed_list.push_back( s ); } } Memo1->Text=my::cout.str(); Memo1->Text=AnsiReplaceStr(Memo1->Text, "\n", "\r\n"); } 手順11:いったん全て保存してビルド&実行

makefile
質問者

お礼

おっしゃるとおりにしてみましたら、memoに表示されました!大変ありがとうございました。 私は全文ボタンのイベント内に書き込んでいたのですが、それでは、main文きちんとを読み込んで表示することはできないのでしょうか。State.hとmain部分と二つに分割しないとできないのでしょうか。

  • BLUEPIXY
  • ベストアンサー率50% (3003/5914)
回答No.2

直接質問文の内容とは関係ないのですけど、 #1の補足で挙げて貰ったプログラムには、 move_goat() move_cabbage() move_man() の定義がないです。 コンパイルしてみたいので、さらに補足していただけませんか?

makefile
質問者

補足

大変遅くなりました。 似たものであり、補足に入りきれなかったので、割愛してしまいました。念のため、上記の定義の前後も付けましたので宜しくお願いします。 public: State() : wolf( false ), goat( false ), cabbage( false ), man( false ), path() { } bool succeeded() const { return( this -> wolf && this -> goat && this -> cabbage && this -> man ); } bool failed() const { return( (wolf == goat && man != wolf) || (goat == cabbage && man != goat) ); } State move_wolf() const { State s = *this; s.path.push_back( *this ); if ( s.wolf == s.man ) { s.wolf = !s.wolf; s.man = !s.man; } return( s ); } State move_goat() const { State s = *this; s.path.push_back( *this ); if ( s.goat == s.man ) { s.goat = !s.goat; s.man = !s.man; } return( s ); } State move_cabbage() const { State s = *this; s.path.push_back( *this ); if ( s.cabbage == s.man ) { s.cabbage = !s.cabbage; s.man = !s.man; } return( s ); } State move_man() const { State s = *this; s.path.push_back( *this ); s.man = !s.man; return( s ); } bool operator== ( const State & s ) const { return( this -> wolf == s.wolf && this -> goat == s.goat && this -> cabbage == s.cabbage && this -> man == s.man ); } };

  • BLUEPIXY
  • ベストアンサー率50% (3003/5914)
回答No.1

ウィンドウズアプリケーションを作成している場合には、mainは要らない(自分では書きません)です。 >どの部分を書き直したらいいのかわかりません そのコンソールプログラムを、(コンパイルできる形のものを)補足でアップできますか?

参考URL:
http://okweb.jp/kotaeru.php3?q=1058834
makefile
質問者

補足

#include <deque> #include <algorithm> #include <iostream> using namespace std; struct State { bool wolf; bool goat; bool cabbage; bool man; deque<State> path; State() : wolf( false ), goat( false ), cabbage( false ), man( false ), path() { } bool succeeded() const { return( this -> wolf && this -> goat && this -> cabbage && this -> man ); }   bool failed() const { return( (wolf == goat && man != wolf) || (goat == cabbage && man != goat) ); } State move_wolf() const { State s = *this; s.path.push_back( *this ); if ( s.wolf == s.man ) { s.wolf = !s.wolf; s.man = !s.man; } return( s ); }            ・            ・ bool operator== ( const State & s ) const {      return( this -> wolf == s.wolf && this -> goat == s.goat && this -> cabbage == s.cabbage && this -> man == s.man ); } }; static ostream & operator << ( ostream & ostr , const State & s ) { ostr << (s.wolf ? "" : "w") << (s.goat ? "" : "g") << (s.cabbage ? "" : "c") << (s.man ? "" : "m") << "-" << (s.wolf ? "w" : "") << (s.goat ? "g" : "") << (s.cabbage ? "c" : "") << (s.man ? "m" : ""); return( ostr ); } static void print_progress( const State & s , const deque<State> & open_list , const deque<State> & closed_list ) { cout << "Testing " << s << endl; cout << "Open List ="; for ( size_t i = 0 ; i < open_list.size() ; i ++ ) { cout << " " << open_list[i]; } cout << endl; cout << "Closed List ="; for ( size_t i = 0 ; i < closed_list.size() ; i ++ ) { cout << " " << closed_list[i]; } cout << endl; } static void print_result( const State & s ) { cout << "Result = "; for ( size_t i = 0 ; i < s.path.size() ; i ++ ) { cout << s.path[i] << " "; } cout << s << endl; } int main( void ) { State start_state; deque<State> open_list; deque<State> closed_list; open_list.push_back( start_state ); while( ! open_list.empty() ) { State s = open_list.front(); open_list.erase( open_list.begin() ); print_progress( s , open_list , closed_list ); cout << endl; if ( s.succeeded() ) { print_result( s ); break; } if ( s.failed() ) { continue; } if ( find( closed_list.begin() , closed_list.end() , s ) == closed_list.end() ) { open_list.push_back( s.move_wolf() ); open_list.push_back( s.move_goat() ); open_list.push_back( s.move_cabbage() ); open_list.push_back( s.move_man() ); closed_list.push_back( s ); } } return( 0 ); } アップしましたが見づらくてすみません。

関連するQ&A

  • C++Builder

    卒業研究で昨日からC++Builderを使うようになったのですが、まったくわかりません。 「慣れれば普通にプログラム作るより簡単だ」と教官はいいいますが… それで昨日課題が出ました。 C++Builderでサイコロを作成し、クリックすれば数字が変わる用にしろ との事。 ずっとやってるのですが…ランダムに数字を表示するのってどうゆうの使うんですか? …もぅ初歩的な質問ですいません… 穴があったら入りたい…

  • C++Builderで実行ファイルが作成されない

     C++Builder6で本に載っているHelloWorldサンプルをビルドしたところ、真っ白なタブが出るだけで何も出力されません。Bin下のbcc32でコマンドラインからコンパイルしてみると、objファイルとtdsファイルが出来ていますが、exeファイルは作成されていませんでした。  どうやれば簡単なコンソールアプリケーションをビルドできるのでしょうか?

  • C++の最初のあたり

    例に自分の名前、生年月日、年齢、住所を画面に表示するプログラムを作ってみてくれませんか? そのプログラムのそれぞれの行にコメントを入れよと出てるんです まだやったばかりで文字の出力法くらいしかやってないですが… これどこが違うんですか #include<iostream> using namespace std; int main() {//main関数を定義する .... cout << "" ×○太郎 << endl ;//自分の名前 .... cout << "April 8, 19○○" << endl ;//生年月日 .... cout << "○○ years old" << endl ;//年齢 .... cout << "taitouku" << endl ;//住所を画面に表示 return 0; }//main関数の終わり そんな難しい事してないから、最初と最後の文はもうこれで行きます

  • C++プログラム問題(初心者です)

    C++の勉強初めて1ヶ月ぐらいです。 以下にある問題がわかりません。 解説付きでお願いします。 [問題] 関数 funcのみを修正することで、標準出力に 2 が表示する。 [プログラム] #include <iostream> using namespace std; int func(int i) {return i;} int main() { int i = 1; cout << ++func(i) << "\n"; return 0; }

  • eclipseのコンソール

    eclipseでコンソールが表示しません。 単純な文字出力です。 ご教授よろしくお願いいたします。 public class AAA { /** * @param args */ public static void main(String[] args) { // TODO 自動生成されたメソッド・スタブ System.out.println("コンソールに表示"); } }

  • C++でどうすればcoutで表示できるのですか?

    C++についての質問です coutで表示するときに kannsuu関数の返り値を main関数とmain関数の cout << ++kannsuu(i) << endl; の部分を変更せずに kannsuu関数のみを変更して インクリメントして「2」と表示したいのですが どのようにすればいいですか? #include <iostream> using namespace std; int kannsuu(int i) {return i;} int main() { int i = 1; cout << ++kannsuu(i) << endl; return 0; }

  • プログラムについてです。

    main関数内でキーボードから入力された2つの整数について、その整数値の和差乗除をユーザ定義関数shisoku()内で計算し、main関数内で結果を出力するプログラムを作成せよ。 ただし、すべて局所変数で構成し、大域変数を使ってはならない。 僕は和差、乗除はできるんですが和差乗除ができません。

  • C++でうるう年判定のプログラムを作りたいのですが

    C++でうるう年判定のプログラムが作りたいのですが・・・ #include <iostream> using namespace std; int main() { return 0; } 問題のこの下の部分の内容が書けません 変数をa % 4という計算と%100と%400をしなければいけないことはわかっています。この式の入れ方がわかりませんif文だとは思っているのですが 表示は「<<a<<"はうるう年です";」と「<<a<<"はうるう年ではありません";」という判定を表示したいです。

  • c#のプログラムについて。

    c#のプログラムについて。 お世話になります。 c#初心者です。 下記の様なコードを記述してますが、 「 Form1.Button1.Visible == false;」の部分で 「'WindowsFormApplication1.Form1'にButton1'の定義がありません。」 と言うエラーが出てしまいます。 どの様に定義して良いのかが分からず、悩んでいます。 どなたかお教え頂きたく宜しくお願い致します。        記 using System; using System.Collections.Generic; using System.Linq; using System.Windows.Forms; namespace WindowsFormsApplication3 { static class Program { /// <summary> /// アプリケーションのメイン エントリ ポイントです。 /// </summary> [STAThread] static void Main() { Application.EnableVisualStyles(); Application.SetCompatibleTextRenderingDefault(false); Application.Run(new Form1()); string result = System.Environment.MachineName; if (result == "xxxxxxx") { Form1.Button1.Visible == false; } } } }

  • windows powershellのコンソール上で表示されなくなった

    windows powershellのコンソール上で表示されなくなった上部のデータ(文字)を参照する方法はないでしょうか。 powershellであるscriptを実行しました。その結果としてコンソール上に表示された情報(文字)が予想以上に多く、 上部の方がコンソールの表示範囲を超えてしまった為参照できなくなってしまいました。 ※cmd.exeでも同じ状況になっていると思います。 状況の説明が難しいのですが、 コンソールウィンドウのスクロールバーを一番上までもっていっても今回のscriptの実行結果として表示された情報の初めの行までは表示出来ない状態です。 予めコンソールの出力をテキストファイルなどにリダイレクトするようにして実行すれば良かったのですが。。 powershellに標準出力されたデータはどこかにログなど残っているのでしょうか? windows、powershellに詳しい方、ご教授お願い致します。