打印自身的程序

原创 2006年05月29日 06:47:00

闲来没事,想起还有这样一个玩意,所以就做了,不知道符合要求不-,-

记得以前有个很短的,不过无法通过编译=。=


// 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;
}

版权声明:本文为博主原创文章,未经博主允许不得转载。

相关文章推荐

程序中 不可打印字符

不可打印字符 转义字符         有些 ASCII 字符是不可打印的。例如退格、另起一行、警报等。C 语言提供了两种方法来表示这种不可打印字符。       第一种方法是...

标签机打印程序研究(二)

完成标签打印

Hadoop程序打印调试

转载   Hadoop程序打印调试 1. System.out 和 System.err Main 在Main函数里使用System.out标准输出和System.err标准错误输出,输出定...

java程序通过 pdf模板 添加pdf表单数据并打印

1:用adobe acrobat设置pdf的表单属性

Caysn打印机IOS平台打印开发包及示例程序_20170610

打印机开发包,接口说明文档,打印示例程序:Caysn打印机IOS开发包、文档、示例程序_20170610 系统要求:IOS8 CPU架构:armv7 armv7s arm64 说明文档:...

数据结构 《4》---- 一个漂亮的打印二叉树的程序

一个漂亮地打印二叉树的一个小程序。

编写一个程序,开启3个线程,这3个线程的ID分别为A、B、C,每个线程将自己的ID在屏幕上打印10遍,要求输出结果必须按ABC的顺序显示;如:ABCABC….依次递推。

编写一个程序,开启3个线程,这3个线程的ID分别为A、B、C,每个线程将自己的ID在屏幕上打印10遍,要求输出结果必须按ABC的顺序显示;如:ABCABC….依次递推。 #include ...
  • zscfa
  • zscfa
  • 2017-07-20 11:25
  • 150

C语言趣味小程序:打印自身

今天在网上看到了一个C语言趣味小程序:打印自身代码。 程序代码如下:  char*s="char*s=%c%s%c;main(){printf(s,34,s,34);}"; main() { ...

CaysnPrinter安卓平台开发包接口说明文档及打印示例程序 - 20160926

接口说明文档下载地址: CaysnPrinter安卓平台开发包接口说明文档 - PrinterLibs For Android_20160926 打印示例程序下载地址: Caysn打印机安...

Caysn打印机IOS平台打印开发包、接口说明文档及示例程序_20170717

打印机开发包,接口说明文档,打印示例程序下载地址:Caysn打印机IOS开发包、文档、示例程序_20170717 Caysn打印机IOS平台开发包,接口说明文档,打印示例程序。  Framework版...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:深度学习:神经网络中的前向传播和反向传播算法推导
举报原因:
原因补充:

(最多只允许输入30个字)