C++ quine

E

Emlyn Corrin

I was bored, so I just wrote a quine (program that will print out it's own
source code when run) in 100% ansi c++, without using any c-library
functions (such as printf), and not making any assumptions on the character
set.
Any comments? bugs? ideas on how to shorten it?

Emlyn


#include <string>
#include <iostream>
using namespace std;
int main() {
string s = "s", s0 = "\n", s1 = "\"", s2 = "\\", s3 = "n", s4 = ";";
string s5 = " string s", s6 = ", s", s7 = " = ", s8 = s7+s1, s9 = "+";
string s10 = "#include <string>", s11 = "#include <iostream>";
string s12 = "using namespace std;", s13 = "int main() {";
string s14 = " return 0;", s15 = "}";
string s20 = " cout<<s10<<s0<<s11<<s0<<s12<<s0<<s13<<s0;";
string s21 = "
cout<<s5<<s8<<s<<s1<<s6<<0<<s8<<s2<<s3<<s1<<s6<<1<<s8<<s2<<s1<<s1<<s6;";
string s22 = "
cout<<2<<s8<<s2<<s2<<s1<<s6<<3<<s8<<s3<<s1<<s6<<4<<s8<<s4<<s1<<s4<<s0;";
string s23 = "
cout<<s5<<5<<s8<<s5<<s1<<s6<<6<<s8<<s6<<s1<<s6<<7<<s8<<s7<<s1;";
string s24 = "
cout<<s6<<8<<s7<<s<<7<<s9<<s<<1<<s6<<9<<s8<<s9<<s1<<s4<<s0;";
string s25 = " cout<<s5<<10<<s8<<s10<<s1<<s6<<11<<s8<<s11<<s1<<s4<<s0;";
string s26 = " cout<<s5<<12<<s8<<s12<<s1<<s6<<13<<s8<<s13<<s1<<s4<<s0;";
string s27 = " cout<<s5<<14<<s8<<s14<<s1<<s6<<15<<s8<<s15<<s1<<s4<<s0;";
string s28 = "
cout<<s5<<20<<s8<<s20<<s1<<s4<<s0<<s5<<21<<s8<<s21<<s1<<s4<<s0<<s5<<22<<s8<<
s22<<s1<<s4<<s0;";
string s29 = "
cout<<s5<<23<<s8<<s23<<s1<<s4<<s0<<s5<<24<<s8<<s24<<s1<<s4<<s0<<s5<<25<<s8<<
s25<<s1<<s4<<s0;";
string s30 = "
cout<<s5<<26<<s8<<s26<<s1<<s4<<s0<<s5<<27<<s8<<s27<<s1<<s4<<s0<<s5<<28<<s8<<
s28<<s1<<s4<<s0;";
string s31 = "
cout<<s5<<29<<s8<<s29<<s1<<s4<<s0<<s5<<30<<s8<<s30<<s1<<s4<<s0<<s5<<31<<s8<<
s31<<s1<<s4<<s0;";
string s32 = "
cout<<s5<<32<<s8<<s32<<s1<<s4<<s0<<s5<<33<<s8<<s33<<s1<<s4<<s0<<s5<<34<<s8<<
s34<<s1<<s4<<s0;";
string s33 = "
cout<<s5<<35<<s8<<s35<<s1<<s4<<s0<<s5<<36<<s8<<s36<<s1<<s4<<s0;";
string s34 = "
cout<<s20<<s0<<s21<<s0<<s22<<s0<<s23<<s0<<s24<<s0<<s25<<s0<<s26<<s0<<s27<<s0
<<s28<<s0;";
string s35 = "
cout<<s29<<s0<<s30<<s0<<s31<<s0<<s32<<s0<<s33<<s0<<s34<<s0<<s35<<s0<<s36<<s0
;";
string s36 = " cout<<s14<<s0<<s15<<s0;";
cout<<s10<<s0<<s11<<s0<<s12<<s0<<s13<<s0;
cout<<s5<<s8<<s<<s1<<s6<<0<<s8<<s2<<s3<<s1<<s6<<1<<s8<<s2<<s1<<s1<<s6;
cout<<2<<s8<<s2<<s2<<s1<<s6<<3<<s8<<s3<<s1<<s6<<4<<s8<<s4<<s1<<s4<<s0;
cout<<s5<<5<<s8<<s5<<s1<<s6<<6<<s8<<s6<<s1<<s6<<7<<s8<<s7<<s1;
cout<<s6<<8<<s7<<s<<7<<s9<<s<<1<<s6<<9<<s8<<s9<<s1<<s4<<s0;
cout<<s5<<10<<s8<<s10<<s1<<s6<<11<<s8<<s11<<s1<<s4<<s0;
cout<<s5<<12<<s8<<s12<<s1<<s6<<13<<s8<<s13<<s1<<s4<<s0;
cout<<s5<<14<<s8<<s14<<s1<<s6<<15<<s8<<s15<<s1<<s4<<s0;

cout<<s5<<20<<s8<<s20<<s1<<s4<<s0<<s5<<21<<s8<<s21<<s1<<s4<<s0<<s5<<22<<s8<<
s22<<s1<<s4<<s0;

cout<<s5<<23<<s8<<s23<<s1<<s4<<s0<<s5<<24<<s8<<s24<<s1<<s4<<s0<<s5<<25<<s8<<
s25<<s1<<s4<<s0;

cout<<s5<<26<<s8<<s26<<s1<<s4<<s0<<s5<<27<<s8<<s27<<s1<<s4<<s0<<s5<<28<<s8<<
s28<<s1<<s4<<s0;

cout<<s5<<29<<s8<<s29<<s1<<s4<<s0<<s5<<30<<s8<<s30<<s1<<s4<<s0<<s5<<31<<s8<<
s31<<s1<<s4<<s0;

cout<<s5<<32<<s8<<s32<<s1<<s4<<s0<<s5<<33<<s8<<s33<<s1<<s4<<s0<<s5<<34<<s8<<
s34<<s1<<s4<<s0;
cout<<s5<<35<<s8<<s35<<s1<<s4<<s0<<s5<<36<<s8<<s36<<s1<<s4<<s0;

cout<<s20<<s0<<s21<<s0<<s22<<s0<<s23<<s0<<s24<<s0<<s25<<s0<<s26<<s0<<s27<<s0
<<s28<<s0;

cout<<s29<<s0<<s30<<s0<<s31<<s0<<s32<<s0<<s33<<s0<<s34<<s0<<s35<<s0<<s36<<s0
;
cout<<s14<<s0<<s15<<s0;
return 0;
}
 
A

Andrew Koenig

Emlyn> I was bored, so I just wrote a quine (program that will print
Emlyn> out it's own source code when run) in 100% ansi c++, without
Emlyn> using any c-library functions (such as printf), and not making
Emlyn> any assumptions on the character set.

Emlyn> Any comments? bugs? ideas on how to shorten it?

Here's a C89 version, written in a form that I find easier to
understand. The interested reader may enjoy translating it to C++:

#include <stdio.h>

char *self[] = {
"#include <stdio.h>",
"",
"char *self[] = {",
"\n",
"\t0",
"};",
"",
"main()",
"{",
"\tchar *p, **s;",
"",
"\tfor (s = self; *s; s++) {",
"\t\tif (**s == '\\n') {",
"\t\t\tchar **t;",
"\t\t\tfor (t = self; *t; t++) {",
"\t\t\t\tputchar ('\\t');",
"\t\t\t\tputchar ('\"');",
"\t\t\t\tfor (p = *t; *p; p++) {",
"\t\t\t\t\tif (*p == '\\t') {",
"\t\t\t\t\t\tputchar ('\\\\');",
"\t\t\t\t\t\tputchar ('t');",
"\t\t\t\t\t} else if (*p == '\"') {",
"\t\t\t\t\t\tputchar ('\\\\');",
"\t\t\t\t\t\tputchar ('\"');",
"\t\t\t\t\t} else if (*p == '\\n') {",
"\t\t\t\t\t\tputchar ('\\\\');",
"\t\t\t\t\t\tputchar ('n');",
"\t\t\t\t\t} else if (*p == '\\\\') {",
"\t\t\t\t\t\tputchar ('\\\\');",
"\t\t\t\t\t\tputchar ('\\\\');",
"\t\t\t\t\t} else",
"\t\t\t\t\t\tputchar (*p);",
"\t\t\t\t}",
"\t\t\t\tputchar ('\"');",
"\t\t\t\tputchar (',');",
"\t\t\t\tputchar ('\\n');",
"\t\t\t}",
"\t\t} else {",
"\t\t\tfor (p = *s; *p; p++) {",
"\t\t\t\tputchar (*p);",
"\t\t\t}",
"\t\t\tputchar ('\\n');",
"\t\t}",
"\t}",
"\treturn 0;",
"}",
0
};

main()
{
char *p, **s;

for (s = self; *s; s++) {
if (**s == '\n') {
char **t;
for (t = self; *t; t++) {
putchar ('\t');
putchar ('"');
for (p = *t; *p; p++) {
if (*p == '\t') {
putchar ('\\');
putchar ('t');
} else if (*p == '"') {
putchar ('\\');
putchar ('"');
} else if (*p == '\n') {
putchar ('\\');
putchar ('n');
} else if (*p == '\\') {
putchar ('\\');
putchar ('\\');
} else
putchar (*p);
}
putchar ('"');
putchar (',');
putchar ('\n');
}
} else {
for (p = *s; *p; p++) {
putchar (*p);
}
putchar ('\n');
}
}
return 0;
}
 
C

chris

Emlyn said:
I was bored, so I just wrote a quine (program that will print out it's own
source code when run) in 100% ansi c++, without using any c-library
functions (such as printf), and not making any assumptions on the character
set.
Any comments? bugs? ideas on how to shorten it?

Emlyn

Here is my attempt :) I'm fairly certain is this standard C++, I also
suspect it can be made shorter by someone with more C++ knowledge than
me. If this gets eaten by your newsreader, note that I don't have a
multi-line literal :)

The only minor point is that I suspect that I can't do
b.insert(it,'\\'), as this will invalidate it (which suggests to me it
would have been sensible to have insert put things in afterwards *sigh*)
, so I should perhaps make a temporary decremented copy, but I can't be
bothered :) Also I could hard-wire the a.insert line, and the b.reserve
line, but wanted to keep them general for now :)

#include<string>
#include<iostream>
using namespace std;
string a("#include<string>\n#include<iostream>\nusing namespace
std\nstring a(\"X\")int main(){\nstring
b=a;\nb.reserve(b.length()*2);\nstring::iterator
it=b.begin();\nwhile(it!=b.end()) {\nif(*it=='\n') {*it='n';
b.insert(it,'\\\\');}\nit++;\n}\na.insert(find(a.begin(),a.end(),'X'),b.begin(),b.end());\ncout<<a<<endl;\n}\n");
int main(){
string b=a;
b.reserve(b.length()*2);
string::iterator it=b.begin();
while(it!=b.end()) {
if(*it=='\n') {*it='n'; b.insert(it,'\\');}
it++;
}
a.insert(find(a.begin(),a.end(),'X'),b.begin(),b.end());
cout<<a<<endl;
}
 
R

Radek Karwowski

I was bored, so I just wrote a quine (program that will print out it's own
Man! You must have been really bored!

Radek
 
B

Buster

I hope the newsreader doesn't mess this up too much. There are no newlines in
the definition of f.

Owner@machine ~/projects/quine
$ cat Quine.cpp
#include <iostream>
#include <string>
template <typename T> char cast (T x) { return static_cast <char> (x); }
void replace (std::string & s, char x, char y) { for (std::string::iterator b =
s.begin (), e = s.end (); b != e; ++ b) if (* b == x) * b = y; }
std::string f ();
int main () {
std::string s (f ());
replace (s, cast (37), cast (10));
std::cout << s << cast (34) << f () << cast (34) << ';' << ' ' << '}' << cast
(10);
}
std::string f () { return "#include <iostream>%#include <string>%template
<typename T> char cast (T x) { return static_cast <char> (x); }%void replace
(std::string & s, char x, char y) { for (std::string::iterator b = s.begin (), e
= s.end (); b != e; ++ b) if (* b == x) * b = y; }%std::string f ();%int main ()
{% std::string s (f ());% replace (s, cast (37), cast (10));% std::cout << s
<< cast (34) << f () << cast (34) << ';' << ' ' << '}' << cast
(10);%}%std::string f () { return "; }

Owner@machine ~/projects/quine
$ g++ -o Quine Quine.cpp

Owner@machine ~/projects/quine
$ ./Quine > Quine2.cpp

Owner@machine ~/projects/quine
$ diff Quine.cpp Quine2.cpp

Owner@machine ~/projects/quine
$
 
B

Buster

Dammit. I didn't notice the "No assumptions on the character set" bit. I'll work
on it.
 
W

White Wolf

Andrew said:
Emlyn> I was bored, so I just wrote a quine (program that will print
Emlyn> out it's own source code when run) in 100% ansi c++, without
Emlyn> using any c-library functions (such as printf), and not making
Emlyn> any assumptions on the character set.

Emlyn> Any comments? bugs? ideas on how to shorten it?

Here's a C89 version, written in a form that I find easier to
understand. The interested reader may enjoy translating it to C++:
[SNIP]

It will take another century or so until the Vatican will be able to decide
if these programs are a form of the virgin birth or self abuse. :)
 
B

Buster

Owner@machine ~/projects/quine
$ g++ -o Quine Quine.cpp; ./Quine > Quine2.cpp; diff Quine.cpp Quine2.cpp

Owner@machine ~/projects/quine
$ cat Quine.cpp
#include <iostream>
#include <string>
#include <locale>
using namespace std;

void qprint (string s)
{
const ctype <char> & ct = use_facet <ctype <char> > (locale ());
for (string::iterator i = s.begin (), e = s.end (); i != e; ++ i)
if (ct.is (ctype_base::upper, * i)) switch (ct.tolower (* i))
{
case 'n': cout << endl; break;
case 's': cout << s; break;
case 'q': cout << '\"'; break;
case 'b': cout << '\\'; break;
}
else cout << * i;
}

int main ()
{
qprint ("#include <iostream>N#include <string>N#include <locale>Nusing
namespace std;NNvoid qprint (string s)N{N const ctype <char> & ct = use_facet
<ctype <char> > (locale ());N for (string::iterator i = s.begin (), e = s.end
(); i != e; ++ i)N if (ct.is (ctype_base::upper, * i)) switch (ct.tolower (*
i))N {N case 'n': cout << endl; break;N case 's': cout << s; break;N
case 'q': cout << 'BQ'; break;N case 'b': cout << 'BB'; break;N }N else
cout << * i;N}NNint main ()N{N qprint (QSQ);N}N");
}
 
A

Agent Mulder

I was bored, so I just wrote a quine

Yesterday night I fell asleep on my keyboard. Again! And when I woke up,
nah, I couldn't belief my eyes! Can you? And I also had that email spammer
sending me happy talk about something. I'll add it below, to feed your e-trash.


#define/**/X
char*d="X0[!4cM,!"
"4cK`*!4cJc(!4cHg&!4c$j"
"8f'!&~]9e)!'|:d+!)rAc-!*m*"
":d/!4c(b4e0!1r2e2!/t0e4!-y-c6!"
"+|,c6!)f$b(h*c6!(d'b(i)d5!(b*a'`&c"
")c5!'b+`&b'c)c4!&b-_$c'd*c3!&a.h'd+"
"d1!%a/g'e+e0!%b-g(d.d/!&c*h'd1d-!(d%g)"
"d4d+!*l,d7d)!,h-d;c'!.b0c>d%!A`Dc$![7)35E"
"!'1cA,,!2kE`*!-s@d(!(k(f//g&!)f.e5'f(!+a+)"
"f%2g*!?f5f,!=f-*e/!<d6e1!9e0'f3!6f)-g5!4d*b"
"+e6!0f%k)d7!+~^'c7!)z/d-+!'n%a0(d5!%c1a+/d4"
"!2)c9e2!9b;e1!8b>e/! 7cAd-!5fAe+!7fBe(!"
"8hBd&!:iAd$![7S,Q0!1 bF 7!1b?'_6!1c,8b4"
"!2b*a,*d3!2n4f2!${4 f. '!%y4e5!&f%"
"d-^-d7!4c+b)d9!4c-a 'd :!/i('`&d"
";!+l'a+d<!)l*b(d=!' m- a &d>!&d'"
"`0_&c?!$dAc@!$cBc@!$ b < ^&d$`"
":!$d9_&l++^$!%f3a' n1 _ $ !&"
"f/c(o/_%!(f+c)q*c %! * f &d+"
"f$s&!-n,d)n(!0i- c- k) ! 3d"
"/b0h*!H`7a,![7* i] 5 4 71"
"[=ohr&o*t*q*`*d *v *r ; 02"
"7*~=h./}tcrsth &t : r 9b"
"].,b-725-.t--// #r [ < t8-"
"752793? <.~;b ].t--+r / # 53"
"7-r[/9~X .v90 <6/<.v;-52/={ k goh"
"./}q; u vto hr `.i*$engt$ $ ,b"
";$/ =t ;v; 6 =`it.`;7=` : ,b-"
"725 = / o`. .d ;b]`--[/+ 55/ }o"
"`.d : - ?5 / }o`.' v/i]q - "
"-[; 5 2 =` it . o;53- . "
"v96 <7 / =o : d =o"
"--/i ]q-- [; h. / = "
"i]q--[ ;v 9h ./ < - "
"52={cj u c&` i t . o ; "
"?4=o:d= o-- / i ]q - "
"-[;54={ cj uc& i]q - -"
"[;76=i]q[;6 =vsr u.i / ={"
"=),BihY_gha ,)\0 " , o [
3217];int i, r,w,f , b ,x ,
p;n(){return r <X X X X X
768?d[X(143+ X r++ + *d ) %
768]:r>2659 ? 59: ( x = d
[(r++-768)% X 947 + 768] ) ?
x^(p?6:0):(p = 34 X X X )
;}s(){for(x= n (); ( x^ ( p
?6:0))==32;x= n () ) ;return x ; }
void/**/main X () { r = p
=0;w=sprintf (X X X X X X o
,"char*d="); for ( f=1;f < * d
+143;)if(33-( b=d [ f++ X ] )
){if(b<93){if X(! p ) o
[w++]=34;for X(i = 35 +
(p?0:1);i<b; i++ ) o
[w++]=s();o[ w++ ]
=p?s():34;} else X
{for(i=92; i<b; i
++)o[w++]= 32;} }
else o [w++ ]
=10;o [
w]=0 ;
puts(o);}






Best Layout:

Don Yang
UCSD
259 E. Bellbrook St.
Covina, CA 91722
USA

http://omoikane.cjb.net


Judges' Comments:

To build:

make dhyang

Try:

cc dhyang.c -o saitou
./saitou > aku.c
cat aku.c

cc aku.c -o soku
./soku > soku.c
cat soku.c

cc soku.c -o zan
./zan > zan.c
cat zan.c

cc zan.c -o aku
./aku | diff - aku.c

A beautiful combination of solving several different problems, but
mostly, the single most impressive layout we've ever seen. Many
programs have *one* interesting layout; this one has four.

It may be informative to run the code through a "beautifier", to
study it, but the layout itself is where most of the interest lies.


Selected Author's Comments:

This one is dedicated to Saitou Hajime fans ^_^x

Instead of making one self reproducing program, what I made was a
program that generates a set of mutually reproducing programs, all of
them with cool layout!

For your enjoyment:
1. Compile saitou.c
2. Run a.out and pipe output to another .c file
3. Compile that file
4. Repeat steps 2 and 3 until eventually the output cycles

To interpret the output: the saitou.c is an image of Saitou Hajime,
which eventually generates three sources files that are images of
"aku soku zan" (sin swift slay), Saitou's motto ;)

For best viewing, set tab spaces to 8 characters, and set your
terminal fonts to as close to square as possible. I hate to do this
but you know, size...

saitou.c and all its output compiles with gcc if your OS uses ASCII
character set. No file is included and all functions assume default
int return type (a source of compile warnings)
 
B

Buster

OK, using locales was silly. Here's my final answer:

Owner@machine ~/projects/quine
$ g++ -o Quine Quine.cpp; ./Quine > Quine2.cpp; diff Quine.cpp Quine2.cpp

Owner@machine ~/projects/quine
$ ./Quine
#include <iostream>
#include <ostream>
#include <string>
using namespace std;

void quine (string s)
{
for (string::iterator b = s.begin (), e = s.end (); b != e; ++ b)
if (* b == '%') switch (* ++ b)
{
case 's': cout << s; break;
case '%': cout << '%'; break;
case 'n': cout << '\n'; break;
case 'q': cout << '\"'; break;
case 'b': cout << '\\'; break;
}
else cout << * b;
}

int main ()
{
quine ("#include <iostream>%n#include <ostream>%n#include <string>%nusing
namespace std;%n%nvoid quine (string s)%n{%n for (string::iterator b = s.begin
(), e = s.end (); b != e; ++ b)%n if (* b == '%%') switch (* ++ b)%n {%n
case 's': cout << s; break;%n case '%%': cout << '%%'; break;%n case
'n': cout << '%bn'; break;%n case 'q': cout << '%b%q'; break;%n case
'b': cout << '%b%b'; break;%n }%n else cout << * b;%n}%n%nint main ()%n{%n
quine (%q%s%q);%n}%n");
}
 
E

Emlyn Corrin

OK, how about this, it should be a bit more readable:

#include <string>
#include <iostream>
using namespace std;

string escape(const string & s) {
string ret(s);
string::size_type i = 0;
while ((i = ret.find_first_of("\\\"", i)) < ret.length()) {
ret.insert(i, "\\");
i += 2;
}
return ret;
}

int main() {
static const string self[] = {
"#include <string>",
"#include <iostream>",
"using namespace std;",
"",
"string escape(const string & s) {",
" string ret(s);",
" string::size_type i = 0;",
" while ((i = ret.find_first_of(\"\\\\\\\"\", i)) < ret.length()) {",
" ret.insert(i, \"\\\\\");",
" i += 2;",
" }",
" return ret;",
"}",
"",
"int main() {",
" static const string self[] = {",
" };",
" for (int i = 0; i < (sizeof self / sizeof *self); ++i) {",
" cout << self << endl;",
" if (i == 15) {",
" for (int j = 0; j < (sizeof self / sizeof *self); ++j) {",
" cout << \" \\\"\" << escape(self[j]) << \"\\\",\" << endl;",
" }",
" }",
" }",
" return 0;",
"}",
};
for (int i = 0; i < (sizeof self / sizeof *self); ++i) {
cout << self << endl;
if (i == 15) {
for (int j = 0; j < (sizeof self / sizeof *self); ++j) {
cout << " \"" << escape(self[j]) << "\"," << endl;
}
}
}
return 0;
}
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,769
Messages
2,569,580
Members
45,055
Latest member
SlimSparkKetoACVReview

Latest Threads

Top