A program that reproduces itself

R

Robert Rotstein

Following is a C program, taken from
http://en.wikipedia.org/wiki/Quine#Sample_quine_in_C,
which has the curious property that, when executed, it produces its own
source code as output.

#include <stdio.h>
char x[]="#include <stdio.h>%cchar x[]=%c%s%c;%cint main()
{printf(x,10,34,x,34,10,10);return 0;}%c";
int main() {printf(x,10,34,x,34,10,10);return 0;}

But I can't figure it out! Specifically, I don't know the significance of
the hard-coded integers, nor how the % formatting characters work in this
instance. Can someone explain just how this works?
 
A

Arthur J. O'Dwyer

Following is a C program, taken from
http://en.wikipedia.org/wiki/Quine#Sample_quine_in_C,
which has the curious property that, when executed, it produces its own
source code as output.

Google "C quine" for many, many more.
#include <stdio.h>
char x[]="#include <stdio.h>%cchar x[]=%c%s%c;%cint main()
{printf(x,10,34,x,34,10,10);return 0;}%c";
int main() {printf(x,10,34,x,34,10,10);return 0;}

But I can't figure it out! Specifically, I don't know the significance of
the hard-coded integers,

They're the ASCII-encoded values of the characters '\n' (10) and '"'
(34). The programmer is relying on the assumption that this program will
only ever be run on implementations using the ASCII character encoding,
which---while generally a reasonable assumption---means that the program
is not a strictly conforming C program.
(The string literal also has an embedded newline, which is definitely
not valid C, but that's just an artifact of your posting technique; the
original program on Wikipedia doesn't have that defect.)
nor how the % formatting characters work in this
instance.

Same way they always do: %s prints a string, %c prints a character.
What don't you understand about them?
Can someone explain just how this works?

Just run through it, with the knowledge that when the programmer writes
"10", he's expecting to see a newline in the output, and when he writes
"34", he's expecting to see a double quote.

-Arthur

Blatant plug: http://www.contrib.andrew.cmu.edu/~ajo/free-software/quine.c
 
M

Mike Wahler

Robert Rotstein said:
Following is a C program, taken from
http://en.wikipedia.org/wiki/Quine#Sample_quine_in_C,
which has the curious property that, when executed, it produces its own
source code as output.

#include <stdio.h>
char x[]="#include <stdio.h>%cchar x[]=%c%s%c;%cint main()
{printf(x,10,34,x,34,10,10);return 0;}%c";
int main() {printf(x,10,34,x,34,10,10);return 0;}

But I can't figure it out! Specifically, I don't know the significance of
the hard-coded integers,

They are character encodings (which assume the ASCII character set,
which makes the program nonportable). 10 is the newline character,
34 is the double-quote character(") (for ASCII).
nor how the % formatting characters work in this
instance.

They work in the 'normal' way defined by the specification
of the 'printf()' function. %c formats a character output,
%s formats a string (char*) output.
Can someone explain just how this works?

The array 'x' is the first ('format') argument to 'printf()'
and 10, 34, x, 34, 10, 10 are the subsequent 'printf()' arguments
whose output formatting is specified by the % specifiers in 'x'.

It might help you see what's happening if you change the
'printf()' to 'sprintf()' (whose first argument is a pointer
to a string where the output will be written (instead of to
'stdout' All the other parameters are the same). Follow that
with a 'puts()' of that string. Note that you'll need to
provide the array for 'sprintf()' to write to.

HTH,
-Mike

-Mike
 
M

Mike Wahler

They are character encodings (which assume the ASCII character set,
which makes the program nonportable). 10 is the newline character,
34 is the double-quote character(") (for ASCII).

Also note that the code can be easily rendered portable:

Replace those ASCII values with character literals.
( '\n' and '"' )

-Mike
 
M

Mike Wahler

Arthur J. O'Dwyer said:
(The string literal also has an embedded newline, which is definitely
not valid C, but that's just an artifact of your posting technique; the
original program on Wikipedia doesn't have that defect.)

Darn! I missed that. Eagle eyes! :)

-Mike
 
J

Jonathan Adams

"Robert Rotstein said:
Following is a C program, taken from
http://en.wikipedia.org/wiki/Quine#Sample_quine_in_C,
which has the curious property that, when executed, it produces its own
source code as output.

#include <stdio.h>
char x[]="#include <stdio.h>%cchar x[]=%c%s%c;%cint main()
{printf(x,10,34,x,34,10,10);return 0;}%c";
int main() {printf(x,10,34,x,34,10,10);return 0;}

But I can't figure it out! Specifically, I don't know the significance of
the hard-coded integers, nor how the % formatting characters work in this
instance. Can someone explain just how this works?

The numbers are various ASCII codes: 10 is '\n' (newline), and 34
is '"' (double quote). The "%c" format specifier says to insert the
next argument as a character, and the "%s" says to print the next
argument as a string. Unfortunately, it can't be clearer without
breaking the quine.

(The string itself has an embedded newline, which is presumably just for
USENET -- you have to remove it (so that the string is on a single line)
to make it work)

- jonathan
 
J

Jonathan Adams

"Mike Wahler said:
Also note that the code can be easily rendered portable:

Replace those ASCII values with character literals.
( '\n' and '"' )

Except that that breaks the quine -- the output looks like:

char x[]="#include <stdio.h>%cchar x[]=%c%s%c;%cint main() {printf(x,'
','"',x,'"','
','
';return 0;}%c";
int main() {printf(x,'
','"',x,'"','
','
';return 0;}

You can't even use '\"' -- the string will no longer compile.

Cheers,
- jonathan
 
F

Flash Gordon

Following is a C program, taken from
http://en.wikipedia.org/wiki/Quine#Sample_quine_in_C,
which has the curious property that, when executed, it produces its
own source code as output.

#include <stdio.h>
char x[]="#include <stdio.h>%cchar x[]=%c%s%c;%cint main()
{printf(x,10,34,x,34,10,10);return 0;}%c";
int main() {printf(x,10,34,x,34,10,10);return 0;}

But I can't figure it out! Specifically, I don't know the
significance of the hard-coded integers, nor how the % formatting
characters work in this instance. Can someone explain just how this
works?

%c takes an integer and prints the character in the execution character
set that corresponds to that character, so for an ASCII implementation
the 10 corresponds to a new line and the 34 corresponds to a '"'. Since
it does not print out a carriage return (code 13 in ASCII) it won't even
work on all ASCII systems. On some you will get
#include <stdio.h>
char x[] ...
especially likely if piping stdout direct to a printer.
 
B

bd

Robert said:
Following is a C program, taken from
http://en.wikipedia.org/wiki/Quine#Sample_quine_in_C,
which has the curious property that, when executed, it produces its own
source code as output.

#include <stdio.h>
char x[]="#include <stdio.h>%cchar x[]=%c%s%c;%cint main()
{printf(x,10,34,x,34,10,10);return 0;}%c";
int main() {printf(x,10,34,x,34,10,10);return 0;}

But I can't figure it out! Specifically, I don't know the significance of
the hard-coded integers, nor how the % formatting characters work in this
instance. Can someone explain just how this works?

%c means to take an integer, and print out the character corresponding to
it. Presumably the numbers are ASCII codes for various characters. Of
course, the Standard does not say that those codes mean the letters that
they do, but one could of course write a quine via different means.
 
D

Daniel Vallstrom

Robert Rotstein said:
Following is a C program, taken from
http://en.wikipedia.org/wiki/Quine#Sample_quine_in_C,
which has the curious property that, when executed, it produces its own
source code as output.

#include <stdio.h>
char x[]="#include <stdio.h>%cchar x[]=%c%s%c;%cint main()
{printf(x,10,34,x,34,10,10);return 0;}%c";
int main() {printf(x,10,34,x,34,10,10);return 0;}

But I can't figure it out! Specifically, I don't know the significance of
the hard-coded integers, nor how the % formatting characters work in this
instance. Can someone explain just how this works?

As others have said, they are hardcoded ASCII values for '\n' (10) and
'"' (34). As a result the wiki-program is not guaranteed to work because
the standard allows for different encodings. Below is a program that is
guaranteed to work. (Can it be improved (while keeping the lines short)?)

$ gcc -std=c99 -Wall -pedantic -O fixpoint.c
$ ./a.out
#include<stdio.h>
char*i="\\#include<stdio.h>",n='\n',q='"',*p=
"%s%cchar*i=%c%c%s%c,n='%cn',q='%c',*p=%c%c%s%c,*m=%c%c%s%c%c;%s%c",*m=
"int main(){return!printf(p,i+1,n,q,*i,i,q,*i,q,n,q,p,q,n,q,m,q,n,m,n);}"
;int main(){return!printf(p,i+1,n,q,*i,i,q,*i,q,n,q,p,q,n,q,m,q,n,m,n);}
$ ./a.out | diff - fixpoint.c
$


Daniel Vallstrom
 

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
474,431
Messages
2,571,677
Members
48,796
Latest member
Greg L.

Latest Threads

Top