https://susam.in/maze/c-quine.html
C Quine
By Susam Pal on 19 Oct 2003
I have been running a mailing list named ncoders for the last several
months now. This mailing list is meant for university students
interested in computers, programming, and network protocols.
A few weeks ago, Vikram Agrawal, a very knowledgeable member of this
mailing list introduced us to an interesting type of computer program
called quine. A quine is a computer program that produces an exact
copy of its own source code as its output. It must not consume any
input, so tricks involving reading its own source code and printing
it are not permitted.
The Classic Quine
Here is a classic quine Vikram shared with us while explaining the
concept of quine:
main(){char*s="main(){char*s=%c%s%c;printf(s,34,s,34);}";printf(s,34,s,34);}
This program is written in K&R C. The current version of GCC compiles
it fine. It is a valid quine on ASCII machines because this program
uses the integer code 34 to print the quotation mark (") character.
This will be explained further in the next section. On another
implementation of the C compiler which does not use ASCII code for
the quotation mark character, the program needs to be modified to the
use the correct code.
Here are some commands that demonstrate the quine:
$ echo -n 'main(){char*s="main(){char*s=%c%s%c;printf(s,34,s,34);}";printf(s,34,s,34);}' > quine.c
$ cc quine.c
$ ./a.out > out.txt
$ diff quine.c out.txt
$ ./a.out
main(){char*s="main(){char*s=%c%s%c;printf(s,34,s,34);}";printf(s,34,s,34);}
The source code of this quine does not end with a newline. The -n
option of GNU echo ensures that the source code file is created
without a terminating newline.
Close Look at the Classic Quine
Let us take a close look at how the quine introduced in the previous
section works. Let us add some newlines in the source code of this
quine for the sake of clarity.
main()
{
char*s="main(){char*s=%c%s%c;printf(s,34,s,34);}";
printf(s,34,s,34);
}
This is almost the same program presented in the previous section.
Only a few newlines have been added to it to make the program easier
to read.
We can see that the printf call uses the string s as the format
string. The format string contains three conversion specifications:
%c, %s, and %c. The arguments for these conversions are: 34, the
string s itself, and 34 once again. Note that 34 is the ASCII code
for the quotation mark character ("). With that in mind, let us now
construct the output of the printf call in a step-by-step manner.
The initial portion of the output consists of the format string from
the beginning up to, but not including, the first conversion
specification copied unchanged to the output stream. Here it is:
main(){char*s=
Then the first conversion specification %c is processed, the
corresponnding argument 34 is taken, and a quotation mark is printed
like this:
"
Then the second conversion specification %s is processed. The
corresponding argument is the string s itself, so the entire string
is printed like this:
main(){char*s=%c%s%c;printf(s,34,s,34);}
Then the third conversion specification %c is processed. The
corresponding argument is 34 again, so once again a quotation mark is
printed like this:
"
Finally, the rest of the format string is copied unchanged to produce
the following output:
;printf(s,34,s,34);}
Here are all the five parts of the output presented next to each
other:
main(){char*s=
"
main(){char*s=%c%s%c;printf(s,34,s,34);}
"
;printf(s,34,s,34);}
Writing them all out in a single line, we get this:
main(){char*s="main(){char*s=%c%s%c;printf(s,34,s,34);}";printf(s,34,s,34);}
This output matches the source code of the program thus confirming
that our program is a quine.
Classic Quine With Terminating Newline
The source code of the classic quine presented above does not
terminate with a newline. I found that a little bothersome because I
am used to always terminating my source code with a single trailing
newline at the end. So I decided to modify that quine a little to
ensure that it always ends with a newline. This is the quine I
arrived at:
main(){char*s="main(){char*s=%c%s%c;printf(s,34,s,34,10);}%c";printf(s,34,s,34,10);}
Compared to the quine in the previous sections, this one has an
additional %c at the end of the formal string and the integer 10 as
the corresponding argument to ensure that the output ends with a
newline. Here is a demonstration of this quine:
$ echo 'main(){char*s="main(){char*s=%c%s%c;printf(s,34,s,34,10);}%c";printf(s,34,s,34,10);}' > quine.c
$ cc quine.c
$ ./a.out > out.txt
$ diff quine.c out.txt
$ ./a.out
main(){char*s="main(){char*s=%c%s%c;printf(s,34,s,34,10);}%c";printf(s,34,s,34,10);}
Comments
---------------------------------------------------------------------
Maze Feed About GitHub Twitter
(c) 2001-2021 Susam Pal