C/C++ program that prints its own source code as its output

后端 未结 8 2266
天命终不由人
天命终不由人 2020-11-29 08:25

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);}


        
相关标签:
8条回答
  • 2020-11-29 09:07
    #include<stdio.h>
    
    int main(void)
    {
        char a[20],ch;
        FILE *fp;
        // __FILE__ Macro will store File Name to the array a[20]
        sprintf(a,__FILE__);  
        // Opening the file in Read mode 
        fp=fopen(a,"r");      
        // Taking character by character from file, 
        // you can also use fgets() to take line by line
        while((ch=fgetc(fp))!=EOF)  
        printf("%c",ch);
        return 0;
    }                              
    
    0 讨论(0)
  • 2020-11-29 09:11

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

    They will usually just throw a warning.

    0 讨论(0)
  • 2020-11-29 09:11

    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.

    0 讨论(0)
  • 2020-11-29 09:20
    main(a){printf(a="main(a){printf(a=%c%s%c,34,a,34);}",34,a,34);}
    
    0 讨论(0)
  • 2020-11-29 09:25

    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);}
    
    0 讨论(0)
  • 2020-11-29 09:27

    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.

    0 讨论(0)
提交回复
热议问题