列印自身的程式

來源:互聯網
上載者:User

閑來沒事,想起還有這樣一個玩意,所以就做了,不知道符合要求不-,-

記得以前有個很短的,不過無法通過編譯=。=

// File Name : print_self.cpp
// Author : keakon
// Create Date : 2006/5/27
// Last Edited Date : 2006/5/28
// Description : Print its own source code in stdout.

#include <algorithm>
//#include <cstdlib> //rand()和srand()需要,但<algorithm>和<fstream>已包含
#include <ctime>
#include <fstream>
#include <iostream>
//#include <iterator> //ostream_iterator需要,但<algorithm>已包含
#include <string>

using namespace std;

string& getCppPath(string& path)
//若只傳遞const char**型的參數,則必須返回一個string
//或一個static的string&,這都是無謂的開銷
//若傳遞string&型的參數,則最好傳遞前就用char*初始化,因此無需其他參數
//返回string&是讓其可以嵌套在其他參數為string&或string的函數中使用

//這個函數做了5個假設:
//1是可執行檔和來源程式的檔案名稱相同(不包括尾碼名)
//2是路徑用“/”作為分隔字元,可以改為“/”在UNIX和Linux下使用
//3是將最後一個“.”作為該可執行檔尾碼名的開始
//4是來源程式路徑為“./”,即當前工程的檔案夾下
//5是該來源程式的尾碼名為.cpp

//可見這個程式大部分都是判斷得出檔案名稱,若允許給main()傳遞參數的話,就簡單多了
{
 typedef string::size_type str_sz;

 const char PATH_DIVIDER[] = "//";
 str_sz index = path.rfind(PATH_DIVIDER); //找最後一個“/”
 const str_sz BEGIN = 0;
 index = (index == string::npos) ? BEGIN : ++index;
 //若沒找到則index為0,否則加1去掉“/”
 path.erase(BEGIN, index); //去掉“/”之前的字元

 const char SUFFIX_BEGIN[] = ".";
 index = path.rfind(SUFFIX_BEGIN); //找最後一個“.”
 if (index == string::npos)
  {index = path.size();}
 //若沒找到則index為最後的元素後面
 //感覺返回npos很麻煩,為什麼不像STL中返回最後一個後面的索引呢=。=
 path.erase(index, path.size() - index); //去掉“.”之後的字元

 const string PATH(".//");
 //預設路徑名,因為在VC++6.0中,來源程式在當前工程的檔案夾下
 //這個不加也行,因為預設就是當前檔案夾
 const string SUFFIX(".cpp");
 //預設尾碼名,因為在VC++6.0中,C++來源程式的尾碼名為.cpp
 path = PATH + path + SUFFIX; //補充檔案名稱的路徑和尾碼名

 return path;
}

void print0(istream& in)
{
 string buf;
 while (getline(in, buf))
  //檔案開啟失敗也沒有危害,因為只是簡單地返回false退出迴圈
  //唯一的缺點是沒有提示出錯罷了,所以我不檢查in了
  //這句改成getline(in, buf, '/0')一次讀取完檔案,理論上可行
  //這假設了檔案中未使用'/0'字元,且檔案大小不超過64k
  //因為string對象的最大字元數為64k
 {
  buf += '/n'; //getline丟棄了分行符號,需要添加
  copy(buf.begin(), buf.end(), ostream_iterator<char>(cout));
  //輸出一行內容到cout
 }
}

void print1(istream& in)
//print0()也可改為用char處理
{
 const streamsize BUF_SIZE = 1024;
 char buf[BUF_SIZE];
 while (in.getline(buf, BUF_SIZE))
  {cout << buf << endl;}
}

void print2(istream& in)
//print1()也可以用copy來實現
{
 const streamsize BUF_SIZE = 1024;
 char buf[BUF_SIZE];
 while (in.getline(buf, BUF_SIZE))
 {
  char* pc = find(buf, buf + BUF_SIZE, '/0');
  //找字串的結尾('/0')
  *pc = '/n'; //修改為換行以輸出
  copy(buf, pc + 1, ostream_iterator<char>(cout));
  //pc + 1為結束邊界
 }
}

int main(int argc, char** agrv)
{
 string path(*agrv); //將可執行檔的路徑儲存為path字串

 ifstream in(getCppPath(path).c_str());
 //從path中提取cpp檔案路徑,然後轉化為C風格的字串用以開啟檔案

 void (* print[3])(istream&); //定義一個函數指標數組
 print[0] = print0;
 print[1] = print1;
 print[2] = print2;

 srand(time(0));
 print[rand() % 3](in); //隨機播放一個函數運行

 in.close();

 return 0;
}

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.