15

Wikipedia says it's called a quine and someone gave the code below:

char*s="char*s=%c%s%c;main(){printf(s,34,s,34);}";main(){printf(s,34,s,34);}

But, obviously you have to add

#include <stdio.h> //corrected from #include <stdlib.h>

so that the printf() could work.

Literally, since the above program did not print #include <stdio.h>, it is not a solution (?)

I am confused about the literal requirement of "print its own source code", and any purpose of this kind of problems, especially at interviews.

3
  • 3
    You need #include <stdio.h> for printf(), not <stdlib.h>. The code is so old that it is not clear that you really need it. But it would be good to upgrade the code to compile cleanly under a modern C compiler. There are issues with no newline at the end of the output, too. That code is most certainly not C++ code. Commented Apr 20, 2012 at 0:32
  • good catch. It is <stdio.h>. And you are right that C++ compilers do not compile the code above, only C compilers do. Commented Apr 20, 2012 at 0:39
  • Why is your code all obfuscated with no spaces? It makes it hard to debug. You seem pretty new to golfing. Let me explain: you have to add #include <stdio.h> to your code. And to do that, you have to print #include <stdio.h> in your quine. So here is a solution: #include <stdio.h>char*s="#include <stdio.h>char*s=%c%s%c;main(){printf(s,34,s,34);}";main(){printf(s,34,s,34);} Commented Dec 14, 2022 at 0:50

11 Answers 11

18

The main purpose of interview questions about quine programs is usually to see whether you've come across them before. They are almost never useful in any other sense.

The code above can be upgraded modestly to make a C99-compliant program (according to GCC), as follows:

Compilation

/usr/bin/gcc -O3 -g -std=c99 -Wall -Wextra -Wmissing-prototypes \
  -Wstrict-prototypes -Wold-style-definition quine.c -o quine

Code

#include <stdio.h>
char*s="#include <stdio.h>%cchar*s=%c%s%c;%cint main(void){printf(s,10,34,s,34,10,10);}%c";
int main(void){printf(s,10,34,s,34,10,10);}

Note that this assumes a code set where " is code point 34 and newline is code point 10. This version prints out a newline at the end, unlike the original. It also contains the #include <stdio.h> that is needed, and the lines are almost short enough to work on SO without a horizontal scroll bar. With a little more effort, it could undoubtedly be made short enough.

Test

The acid test for the quine program is:

./quine | diff quine.c -

If there's a difference between the source code and the output, it will be reported.


An almost useful application of "quine-like" techniques

Way back in the days of my youth, I produced a bilingual "self-reproducing" program. It was a combination of shell script and Informix-4GL (I4GL) source code. One property that made this possible was that I4GL treats { ... } as a comment, but the shell treats that as a unit of I/O redirection. I4GL also has #...EOL comments, as does the shell. The shell script at the top of the file included data and operations to regenerate the complex sequence of validation operations in a language that does not support pointers. The data controlled which I4GL functions we generated and how each one was generated. The I4GL code was then compiled to validate the data imported from an external data source on a weekly basis.

If you ran the file (call it file0.4gl) as a shell script and captured the output (call that file1.4gl), and then ran file1.4gl as a shell script and captured the output in file2.4gl, the two files file1.4gl and file2.4gl would be identical. However, file0.4gl could be missing all the generated I4GL code and as long as the shell script 'comment' at the top of the file was not damaged, it would regenerate a self-replicating file.

Sign up to request clarification or add additional context in comments.

1 Comment

Thanks for the update C99 version. And the "useful application" is very appreciated!
16

The trick here is that most compilers will compile without requiring you to include stdio.h.

They will usually just throw a warning.

1 Comment

It's probably worth expanding this answer to explain the rules as to how implicitly-defined functions are inferred according to the Standard.
6

A quine has some depth roots in fixed point semantics related to programming languages and to executions in general. They have some importance related to theoretical computer science but in practice they have no purpose.

They are a sort of challenge or tricks.

The literal requirement is just you said, literal: you have a program, its execution produces itself as the output. Nothing more nor less, that's why it's considered a fixed point: the execution of the program through the language semantics has itself as its ouput.

So if you express the computation as a function you'll have that

f(program, environment) = program

In the case of a quine the environment is considered empty (you don't have anything as input neither precomputed before)

1 Comment

Also thank you for the explanation for the practical value of a quine.
6

You can also define printf's prototype by hand.

const char *a="const char *a=%c%s%c;int printf(const char*,...);int main(){printf(a,34,a,34);}";int printf(const char*,...);int main(){printf(a,34,a,34);}

Comments

2

Quine (Basic self-relicating code in c++`// Self replicating basic code

[http://www.nyx.net/~gthompso/quine.htm#links] [https://pastebin.com/2UkGbRPF#links]

// Self replicating basic code

#include <iostream>     //1 line   
#include <string>       //2 line    
using namespace std;        //3 line    
                //4 line    
int main(int argc, char* argv[])    //5th line  
{
        char q = 34;            //7th line  
        string l[] = {      //8th line  ---- code will pause here and will resume later in 3rd for loop
 " ",
 "#include <iostream>       //1 line   ",
 "#include <string>     //2 line    ",
 "using namespace std;      //3 line    ",
 "              //4 line    ",
 "int main(int argc, char* argv[])  //5th line  ",
 "{",
 "        char q = 34;          //7th line  ",
 "        string l[] = {        //8th line  ",
 "        };                //9th resume printing end part of code  ",      //3rd loop starts printing from here
 "        for(int i = 0; i < 9; i++)        //10th first half code ",
 "                cout << l[i] << endl;     //11th line",
 "        for(int i = 0; i < 18; i++)   //12th whole code ",
 "                cout << l[0] + q + l[i] + q + ',' << endl;    13th line",
 "        for(int i = 9; i < 18; i++)   //14th last part of code",
 "                cout << l[i] << endl;     //15th line",
 "        return 0;         //16th line",
 "}             //17th line",
        };                                          //9th resume printing end part of code  
        for(int i = 0; i < 9; i++)      //10th first half code 
                cout << l[i] << endl;       //11th line
        for(int i = 0; i < 18; i++) //12th whole code 
                cout << l[0] + q + l[i] + q + ',' << endl;  13th line
        for(int i = 9; i < 18; i++) //14th last part of code
                cout << l[i] << endl;       //15th line
        return 0;           //16th line
}               //17th line

Comments

1

Here's a version that will be accepted by C++ compilers:

#include<stdio.h>
const char*s="#include<stdio.h>%cconst char*s=%c%s%c;int main(int,char**){printf(s,10,34,s,34);return 0;}";int main(int,char**){printf(s,10,34,s,34);return 0;}

test run:

$ /usr/bin/g++ -o quine quine.cpp
$ ./quine | diff quine.cpp - && echo 'it is a quine' || echo 'it is not a quine'
it is a quine

The string s contains mostly a copy of the source, except for the content of s itself - instead it has %c%s%c there.

The trick is that in the printf call, the string s is used both as format and as the replacement for the %s. This causes printf to put it also into the definition of s (on the output text, that is)

the additional 10 and 34s correspond to the linefeed and " string delimiter. They are inserted by printf as replacements of the %cs, because they would require an additional \ in the format-string, which would cause the format- and replacement-string to differ, so the trick wouldn't work anymore.

1 Comment

You probably ought to mention that the numeric values 10 and 34 are dependent on the host character encoding, and need to be changed for platforms where linefeed and double-quote have different character values (e.g. ECBDIC).
0

Not sure if you were wanting the answer on how to do this. But this works:

#include <cstdio>
int main () {char n[] = R"(#include <cstdio>
int main () {char n[] = R"(%s%c"; printf(n, n, 41); })"; printf(n, n, 41); }

If you are a golfer, this is a more minified version:

#include<cstdio>
int main(){char n[]=R"(#include<cstdio>
int main(){char n[]=R"(%s%c";printf(n,n,41);})";printf(n,n,41);}

Comments

0

My version without using %c:

#include <stdio.h>
#define S(x) #x
#define P(x) printf(S(S(%s)),x)
int main(){char y[5][300]={
S(#include <stdio.h>),
S(#define S(x) #x),
S(#define P(x) printf(S(S(%s)),x)),
S(int main(){char y[5][300]={),
S(};puts(y[0]);puts(y[1]);puts(y[2]);puts(y[3]);P(y[0]);putchar(',');puts(S());P(y[1]);putchar(',');puts(S());P(y[2]);putchar(',');puts(S());P(y[3]);putchar(',');puts(S());P(y[4]);puts(S());fputs(y[4],stdout);})
};puts(y[0]);puts(y[1]);puts(y[2]);puts(y[3]);P(y[0]);putchar(',');puts(S());P(y[1]);putchar(',');puts(S());P(y[2]);putchar(',');puts(S());P(y[3]);putchar(',');puts(S());P(y[4]);puts(S());fputs(y[4],stdout);}

Comments

0

From a theoretical point of view, such programs stem from a fundamental theorem in the Theory of Computation, known as the recursion theorem. For a proof of this theorem you may see section 6.1 of the following book.

  • Michael Sipser, An Introduction to Theory of Computation, Gengage Learning, 3rd Edition, 2013.

Here, I try to implement the proof of the recursion theorem mentioned in the book in C++. Although this is not the shortest program of this kind, hopefully it is much more understandable.

In the program below, the function self produces a copy of itself, puts it into the variable tape, and prints it. self is composed of two parts A and B. Part A says what will be written in part B and part B says what was written in part A. We avoid circular definition with the aid of an auxiliary function q. Note that parts A and B are introduced for making things more clear and can be discarded altogether, so you can simply implement self as the output shows.

To run this code, you need the {fmt} library installed.

#include <fmt/printf.h>


using namespace std;


void println(string str) {
    fmt::printf(str);
    fmt::printf("\n");
}


string q(string output) {
    string strP = "void self() { string tape = %s;";
    output = fmt::sprintf("\"%s\"", output);
    strP = fmt::sprintf(strP, output);
    return strP;
}


#define A void self() { string tape = " tape = q(tape) + tape; println(tape); return; }";
#define B tape = q(tape) + tape; println(tape); return; }
#define SELF A B
SELF


int main() {
    self();
}

The output will be

void self() { string tape = " tape = q(tape) + tape; println(tape); return; }"; tape = q(tape) + tape; println(tape); return; }

Comments

-1
/*  C/C++ code that shows its own source code without and with File line number and C/C++ code that shows its own file path name of the file. With Line numbers */

#include<stdio.h>

#include<string.h>

#include<iostream>

using namespace std;



#define SHOW_SOURCE_CODE 

#define SHOW_SOURCE_FILE_PATH

/// Above two lines are user defined Macros

int main(void) {



/* shows source code without File line number. 

#ifdef SHOW_SOURCE_CODE

        // We can append this code to any C program

    // such that it prints its source code.



    char c;

    FILE *fp = fopen(__FILE__, "r");



    do

    {

        c = fgetc(fp);

        putchar(c);

    }

    while (c != EOF);



    fclose(fp);

          // We can append this code to any C program

    // such that it prints its source code.



#endif

*/

#ifdef SHOW_SOURCE_FILE_PATH



       /// Prints location of C this C code.

   printf("%s \n",__FILE__);



#endif


#ifdef SHOW_SOURCE_CODE
        /// We can append this code to any C program
    /// such that it prints its source code with line number.

unsigned long ln = 0;
 FILE *fp = fopen(__FILE__, "r");
int prev = '\n';
int c;  // Use int here, not char
while((c=getc(fp))!=EOF) {
  if (prev == '\n'){
    printf("%05lu ", ++ln);
  }
  putchar(c);
  prev = c;
}
if (prev != '\n') {
  putchar('\n');  /// print a \n for input that lacks a final \n
}
printf("lines num: %lu\n", ln);

    fclose(fp);
          /// We can append this code to any C program
    /// such that it prints its source code with line number.

#endif

    return 0;
}

Comments

-2
main(a){printf(a="main(a){printf(a=%c%s%c,34,a,34);}",34,a,34);}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.