2011-02-19 12 views
0

私は加速C++の中で最後の練習に私の解決策を問うています:自己再生プログラム

自己再生プログラムを書きます。そのようなプログラムは、入力を行わず、実行すると、それ自身のソーステキストのコピーを標準出力ストリームに書き出すものです。

私のソリューション:

using std::string; 
using std::cout; 
using std::endl; 
using std::ifstream; 
using std::getline; 

void selfReproduce16_1() 
{ 
    ifstream thisFile("C:\\Users\\Kevin\\Documents\\NetBeansProjects\\Accelerated_C++_Exercises\\Chapter_16.cpp", ifstream::in); 

    string curLine; 

    bool foundHeader = false; 

    while(getline(thisFile, curLine)) 
    { 
     if(!curLine.compare("void selfReproduce16_1()") || foundHeader) 
     { 
      foundHeader = true; 
      cout << curLine << endl; 
     } 

    } 

} 

これが唯一の解決策(この機能)のソーステキストを出力します。これは彼らが念頭に置いていた解決策ですか?

ソースファイルの場所をハードコードする必要のないダイナミックなソリューションが欲しいです。しかし、実行時にソースファイルの場所を自動的に取得する方法はわかりません。

これに関連するもう一つの点は、「インクルード」ファイルを含めることであり(関数呼び出しに遭遇したとき)、関数が格納されているソースファイルの場所を自動的に取得することです。 「自己再生」プログラム。

これはC++で可能ですか?もしそうなら、どうですか?

+4

'ifstream'を使用するには、ルール「このようなプログラムは何も入力しませんものです」に違反します。 –

+1

非常にスマートなソリューションです。ソースファイルを読み込んで出力します。そしてそれは "Accelerated C++"を読んだ後に行われます。私はそれもあまりにも*加速されていると言わなければならない*解決策:D – Nawaz

+0

私はこの "近代的な"コンピュータープログラミングには本当に不公平なものがあると思う。私は20年間プログラマをしてきましたが、私はQuineを書く方法を知らず...これらの初心者は、350ページのAcceleratedマニュアル(Amazonでチェック)を読んでQuinesを書くことができます...私は悲しいです、とても悲しい。悲しいことに、私は料理人になるか、似たようなことをして、他の人に仕事を盗みます! :-) – xanatos

答えて

8

印刷するプログラムは、Quineと呼ばれます。

あなたの解決策は有効ではないと考えられます。通常、クインズはファイルを読み込むことも、他の種類の入力を取得することもできません。 Quine C++プログラム、hereを書くことは可能です。あなたはいくつかの言語で多くのquineの実装を見つけることができます。

4

私は(

は、あなたが知っている、メイン関数内の引数(ソースファイルの場所をハードコーディングする必要はありません1)動的なソリューションの多くを希望すなわちargcとargv)。最初のargvはプログラム実行ファイルのファイル名です。したがって、.exeを削除して.cppに置き換えるだけでよいのです。または、ファイル名からフォルダを抽出し、すべてのソースファイルを検索して出力することもできます。私はあなたにそれを理解させます。実行ファイルの名前を印刷するには、次のようにします。

#include <iostream> 

int main(int argc, char** argv) { 
    std::cout << argv[0] << std::endl; 
    return 0; 
}; 

システム上で何が表示されているのかを確認してください。フルパスが表示されない場合、すべてのファイルオープン操作が同じ開始相対ディレクトリから行われることを心配しないでください。したがって、実行可能ファイルの相対ディレクトリを取得すると、相対ディレクトリもソースに与えられます(同じフォルダ)。

+0

ありがとう!これはまさに私の頭の中に現れたシナリオに対する答えです。 – Kevin

0

私はC++で書かれたシンプルなquineです。入力を一切使用しません。私は、これらの行に沿って何かを探していたと思います。なぜなら、明示的に入力を排除しているからです(それ以外は、ソースファイルを読むあなたの解決策は良いものです。

https://gist.github.com/3363087

0

私はちょうどそのレッスンを終えました。テキストファイルを開かないものを書くのは難しくありません。あなたがしなければならないことは、文字列のベクトルを使うことです。ただし、ベクトルのプッシュを除いて、コードの各行を押します。実際にはループのために使用します。実際には自分のコードを見ることができます。 。あなたが得られないかもしれない唯一のものはforループです。私はそれを使っています(auto b:a)bはiteratorであり、autoはそれを宣言する簡単な方法です。ここにソースコードがあります。

#include "stdafx.h" 
#include <vector> 
#include <string> 
#include <iostream> 
using namespace std; 
int main() 
{ 
vector<string> a; 
push: 
a.push_back("#include \"stdafx.h\""); 
a.push_back("#include <vector>"); 
a.push_back("#include <string>"); 
a.push_back("#include <iostream>"); 
a.push_back("using namespace std;"); 
a.push_back("using namespace std;"); 
a.push_back("int main()"); 
a.push_back("{"); 
a.push_back("vector<string> a;"); 
a.push_back("push:"); 
a.push_back("for(auto b:a)"); 
a.push_back("{"); 
a.push_back("cout << b << endl;"); 
a.push_back("if(b == \"push:\")"); 
a.push_back("{"); 
a.push_back("for(auto c:a)"); 
a.push_back("{"); 
a.push_back("cout << \"a.push_back(\\\"\" << c << \\\"\";\" << endl;"); 
a.push_back("}"); 
a.push_back("}"); 
a.push_back("}"); 
a.push_back("return 0;"); 
a.push_back("}"); 
for(auto b:a) 
{ 
    cout << b << endl; 
    if(b == "push:") 
    { 
     for(auto c:a) 
     { 
      cout << "a.push_back(\"" << c << "\");" << endl; 
     } 
    } 
} 
return 0; 
} 
0

インラインアセンブリが許可されている場合は、これをソースファイルのどこかに配置します。 GNUアセンブラに依存しているため、外部からのデータを埋め込むことができます。

#include <cstdint> 
extern "C" 
{ 
#if __gnu_linux__ 

#define BLOB(identifier,filename) \ 
asm(".pushsection .data\n" \ 
    "\t.local " #identifier "_begin\n" \ 
    "\t.type " #identifier "_begin, @object\n" \ 
    "\t.align 16\n" \ 
    #identifier "_begin:\n" \ 
    "\t.incbin \"" filename "\"\n\n" \ 
\ 
    "\t.local " #identifier "_end\n" \ 
    "\t.type " #identifier "_end, @object\n" \ 
    "\t.align 1\n" \ 
    #identifier "_end:\n" \ 
    "\t.byte 0\n" \ 
    "\t.popsection\n"); \ 
\ 
extern const uint8_t identifier##_begin[];\ 
extern const uint8_t identifier##_end[] 

#elif _WIN32 

#define BLOB(identifier,filename) \ 
asm(".data\n" \ 
    "\t.align 16\n" \ 
    #identifier "_begin:\n" \ 
    "\t.incbin \"" filename "\"\n\n" \ 
\ 
    "\t.align 1\n" \ 
    #identifier "_end:\n" \ 
    "\t.byte 0\n" \ 
    "\t.text\n"); \ 
\ 
extern const uint8_t identifier##_begin[];\ 
extern const uint8_t identifier##_end[] 

#else 
    #error "Cannot include binary files" 
#endif 
} 

BLOB(source,__FILE__); 

は今、次の2つの識別子source_beginsource_endを持っています。アレイをループし、お気に入りのインターフェイスでデータを印刷します。

int main() 
    { 
    auto ptr=source_begin; 
    auto ptr_end=source_end; 
    while(ptr!=ptr_end) 
     { 
     putchar(*ptr); 
     ++ptr; 
     } 
    return 0; 
    } 

デモ:http://coliru.stacked-crooked.com/a/d283f6dd9118b164

関連する問題