如何写一个程序打印自己的源代码

本文介绍了一个编程问题,要求编写一个程序打印其自身的源代码,但不能读写文件。作者提供了两种解法,一种基础版本通过读取文件,另一种加强版使用递归函数模拟输出。最终给出了一个利用字符串数组和递归实现的详细代码示例。
摘要由CSDN通过智能技术生成

前言

在上课的时候,突然想起很久以前的一个有趣的问题。

题目描述

写一个程序打印自己的源代码。

假设程序的源代码是:

#include <bits/stdc++.h>
using namespace std;
signed main() {
  cout << "Hello World" << endl;
  return 0;
}

那么你的答案应该打印:

#include <bits/stdc++.h>
using namespace std;
signed main() {
  cout << "Hello World" << endl;
  return 0;
}

在查看答案前,建议先自行思考。

解法

直接读取程序的源代码文件,然后打印源代码即可。

#include <bits/stdc++.h>
using namespace std;
const int N = 2e5 + 5;
char s[N];
signed main() {
  ifstream f("test.cpp");
  while (f.getline(s, N))
    cout << s << endl;
  return 0;
}

但是这种方法太low了,于是就有了加强版。

加强版

写一个程序打印自己的源代码,且禁止读写文件。

解法

这个题目最大的难点在于使用 cout 打印一个语句后,又产生一条新的语句,导致需要打印无尽的语句。

例如,

#include <bits/stdc++.h>
using namespace std;
signed main() {
  cout << "#include <bits/stdc++.h>" << endl;
  cout << "using namespace std;" << endl;
  cout << "signed main() {" << endl;
  cout << "  cout << \"#include <bits/stdc++.h>\" << endl;" << endl;
  cout << "  cout << \"using namespace std;\" << endl;" << endl;
  cout << "  cout << \"signed main() {\" << endl;" << endl;
  return 0;
}

如果我们有这样一个函数 f ( s ) f(s) f(s),可以同时打印 s s s 语句和调用它的语句就好了。

例如,

调用 f("#include <bits/stdc++.h>") 同时在恰当的位置打印 #include <bits/stdc++.h>f("#include <bits/stdc++.h>")

f 的实现

void f(string s, int x, int y) {
  ans[x] = s;
  ans[y] += ' ';
  ans[y] += ' ';
  ans[y] += 'f';
  ans[y] += '(';
  ans[y] += (char)34;
  ans[y] += s;
  ans[y] += (char)34;
  ans[y] += ',';
  ans[y] += ' ';
  ans[y] += to_string(x);
  ans[y] += ',';
  ans[y] += ' ';
  ans[y] += to_string(y);
  ans[y] += ')';
  ans[y] += ';';
}

在调用 f f f 后,在第 x x x 行打印 s s s 语句,在第 y y y 行打印调用它的语句。

注意在打印双引号的时候如果直接使用 " 会产生嵌套,要使用 (char)34 替代。

代码实现

#include <bits/stdc++.h>
using namespace std;
string ans[55];
void f(string s, int x, int y) {
  ans[x] = s;
  ans[y] += ' ';
  ans[y] += ' ';
  ans[y] += 'f';
  ans[y] += '(';
  ans[y] += (char)34;
  ans[y] += s;
  ans[y] += (char)34;
  ans[y] += ',';
  ans[y] += ' ';
  ans[y] += to_string(x);
  ans[y] += ',';
  ans[y] += ' ';
  ans[y] += to_string(y);
  ans[y] += ')';
  ans[y] += ';';
}
signed main() {
  f("#include <bits/stdc++.h>", 1, 23);
  f("using namespace std;", 2, 24);
  f("string ans[55];", 3, 25);
  f("void f(string s, int x, int y) {", 4, 26);
  f("  ans[x] = s;", 5, 27);
  f("  ans[y] += ' ';", 6, 28);
  f("  ans[y] += ' ';", 7, 29);
  f("  ans[y] += 'f';", 8, 30);
  f("  ans[y] += '(';", 9, 31);
  f("  ans[y] += (char)34;", 10, 32);
  f("  ans[y] += s;", 11, 33);
  f("  ans[y] += (char)34;", 12, 34);
  f("  ans[y] += ',';", 13, 35);
  f("  ans[y] += ' ';", 14, 36);
  f("  ans[y] += to_string(x);", 15, 37);
  f("  ans[y] += ',';", 16, 38);
  f("  ans[y] += ' ';", 17, 39);
  f("  ans[y] += to_string(y);", 18, 40);
  f("  ans[y] += ')';", 19, 41);
  f("  ans[y] += ';';", 20, 42);
  f("}", 21, 43);
  f("signed main() {", 22, 44);
  f("  for (int i = 1; i <= 52; i++)", 49, 45);
  f("    cout << ans[i] << endl;", 50, 46);
  f("  return 0;", 51, 47);
  f("}", 52, 48);
  for (int i = 1; i <= 52; i++)
    cout << ans[i] << endl;
  return 0;
}

如果有其他更好的做法,欢迎在评论区提出,感谢你的阅读。

  • 23
    点赞
  • 21
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值