Jim Lawless' Blog


A Quine in C

Originally published on: Tue, 28 Apr 2009 00:11:12 +0000

Please note! If you're having difficulties compiling the C source code presented below, please see my post: Compiling C from the Command Line with Pelles C

A quine is a program that produces its own source as its output.

I'd never written one before, so on Pi Day of this year ( 3/14 ) I gave it a go. Here's the result of my effort. You'll need to scroll waaaay over to the right ...


#include <stdio.h>
#define E(x) putchar(x)
char *s="#include <stdio.h>@10#define E(x) putchar(x)@10char *s=@34~main() {char *p=s;for(;*s;s++){if(*s==64){E((10*(s[1]-48))+(s[2]-48));s+=2;}else if(*s==126){while(*p){E(*p++);} E(34); E(59);E(10);}else{E(*s);}}}";
main() {char *p=s;for(;*s;s++){if(*s==64){E((10*(s[1]-48))+(s[2]-48));s+=2;}else if(*s==126){while(*p){E(*p++);} E(34); E(59);E(10);}else{E(*s);}}}

The issue that I found myself dealing with was the string metacharacters the slash and the double-quote. If I used any of the metacharacters in the source string, I would need to find a way to regenerate the character in its escaped form as well as the raw form.

My solution was to loop through the string s and use my own metacharacter @ to indicate that the next two digits will represent the ASCII character that is to be written. In checking for the metacharacter, I use the ASCII value of @ (64), so if you're trying this out on a machine that uses EBCDIC or something other than ASCII, the code won't work.

The appearance of @10 in the string will cause the program to output a character with an ASCII value of ten ( a newline. ) The appearance of @34 in the string will yield a double-quotation mark. @59 will yield a semicolon.

The next metacharacter my routine uses is the tilde ~ character to denote the end of the prologue of the output. The quine is really three sections wide.

  1. The prologue code ( #include's and such and the beginning of the source string definition... )
  2. The string containing the source code
  3. The body of the program that produces the output.

I abbreviated putchar() as E() with a macro so that the source wouldn't be any lengthier than it needed to be.

To generate the quine, the code first outputs the prologue, then a double-quote, then the complete source string, then another double-quote, then a semicolon, then a preserved section of the source-string that appears after the tilde ( the main() function. )

Unless otherwise noted, all code and text entries are Copyright ©2009 by James K. Lawless



Views expressed in this blog are those of the author and do not necessary reflect those of the author's employer. Views expressed in the comments are those of the responding individual.

stumbleupon Save to StumbleUpon
digg Digg it
reddit Save to Reddit
facebook Share on Facebook
twitter Share on Twitter
aolfav More bookmarks


Previous post: Stacking Images with PerlMagick
Next post:Envy


About Jim ...


Click **here**
to try out MailWrench;
a command-line SMTP /
SMTPS (Google Gmail)
mailer for Windows.


Follow me on Twitter

http://twitter.com/lawlessGuy


Recent Posts

A JavaScript REPL for Android Devices

MailSend is Free

My Blog Engine

The October 10th Bug

A Review of Kevin Mitnick's Book Ghost in the Wires

Spellbound by Web Programming

Backlinks to my Blog Posts

Play MP3 Files with Python on Windows


Random Posts

BBS Fun in the Eighties

Setting Text Color in a Batch File

An Interview with Brad Templeton

WSH JavaScript Includes

Thwarting HTTP Referer Trackbacks

The Protection Racket

A DSL in JavaScript

An Interview with Game Developer James Hague

Obfuscated C

Twimmando No More


Full List of Posts

http://www.mailsend-online.com/bloglist.htm


Recent Posts from my Other Blog

Remembering Dr. San Guinary

Why Some Web Sites will go Dark on Jan 18th

SNL Superhero Skit

More Ruby Games

My Ruby Game Challenge Entry

Steal this Bookmarklet

Nerd Toys

Learn New Jargon, You Must

Spot the Wiebe

Tech Magazine Glory Days

Book Review : Paull Allen - Idea Man

A 90's Experiment in Online Systems - The U.S. West CommunityLink Service