C Challenge: Self-Printing Program

Source: Programming Challenges - Self-Printing Program - Cprogramming.com


Here's a nice challenge for all you programming freaks.

Write a program that, when run, will print out its source code. This source code, in turn, should compile and print out itself.


Discuss the code with fellow CEans in this thread. Googling is good, but it doesn't add value to your knowledge.

Replies

  • Kaustubh Katdare
    Kaustubh Katdare
    Hah, No one? 😀

    Too tough?
  • Ashraf HZ
    Ashraf HZ
    That sounds doable 😛 Have a function to copy itself and read out its source code.

    *rubs chin*
  • anuragh27crony
    anuragh27crony
    Good question...this question i have encountered....during my placements.....

    Simple technique is ...to use %s in a pointer to char which contains itself while printing.

    char *temp="include void main() { char *temp=%s ...and so on";
  • bayazidahmed
    bayazidahmed
    The_Big_K
    Hah, No one? 😀

    Too tough?
    Nah! Too easy.
  • Kaustubh Katdare
    Kaustubh Katdare
    Alright, alright! 😁

    Why don't you help others come up with a solution then? 😉
  • Ashutosh_shukla
    Ashutosh_shukla
    If the following code is saved as PROG1.C then on running this code output is the code itself.
    #include
    #include
    #include
    void main()
    {
     FILE *fp;
     char str[80];
     int i=0;
     clrscr();
     fp=fopen("PROG1.C","r");
     if(fp==NULL)
     {
      printf("File could not be opened.");
      getch();
      exit(1);
     }
     while(fgets(str,80,fp)!=NULL)
     {
      i++;
      printf("%d",i);
      printf("%s",str);
     }
     getch();
    }
    
  • anusha.p.s
    anusha.p.s
    Execution of above code always says that "file cannot be opened"
  • Ashutosh_shukla
    Ashutosh_shukla
    you save it as prog1.c in bin folder of turbo c then run it
  • muts
    muts
    #include
    char *program = "#include %cchar *program = %c%s%c;%cint main()%c{%c
    printf(program, 10, 34, program, 34, 10, 10, 10, 10, 10, 10);%c return 0;%c}%c";
    int main()
    {
    printf(program, 10, 34, program, 34, 10, 10, 10, 10, 10, 10);
    return 0;
    }

    tell me about that
  • shalini_goel14
    shalini_goel14
    Is Java allowed?
  • MaRo
    MaRo
    Yes, you can do it in Java, the point about the algorithm not actual source code.
  • shalini_goel14
    shalini_goel14
    I forgot my C almost ;-) ,even I don't like C language and title of this thread includes C challenge.I could not stop myself from writing in Java.Thanks Maro Sir for allowing me in Java.

    [SIZE=2]/*
    * PrintMe.java
    *
    * Created on December 5, 2008, 9:39 AM
    *
    * To change this template, choose Tools | Template Manager
    * and open the template in the editor.
    */
    package myjava;
    import java.io.File;
    import java.io.FileInputStream;
    import java.io.IOException;
    /**
    *
    * @author shalinig
    */
    public class PrintMe {
    
    /**
    *@param args the command line arguments
    */
    public static void main(String args[]){
    try{
    File fileObj =new File("src/myjava","PrintMe.java");
    FileInputStream fin=new FileInputStream(fileObj);//opens input file if already exists else create one.
    int i;
    System.out.println("File name is::"+fileObj.getAbsolutePath());//gives absolute path of the file
    System.out.println("******************************************************************\n");
    //reads character until EOF is encountered
    do{
    i=fin.read();//reads a single byte from the file and returns the byte as an integer value.
    if(i!=-1) //returns -1 when end of file is reached
    {
    System.out.print((char) i);
    }
    }while(i!=-1);
    fin.close();//close the file
    
    } catch(IOException e){
    e.printStackTrace();
    }
    System.out.println("End of File Printing");
    System.out.println("******************************************************************\n");
    }
    
    }
    [/SIZE]
    File fileObj =new File("src/myjava","PrintMe.java");
    In the above line- pass directory name where your this program is saved as first parameter and second parameter will be same as the class name with .java extension
  • sumitjami
    sumitjami
    Moderator can u plz upload the exact code coz there is no correct source code........in the above given codes none did compile itself ......u had written ....
    "This source code, in turn, should compile and print out itself"
  • shalini_goel14
    shalini_goel14
    sumitjami
    Moderator can u plz upload the exact code coz there is no correct source code........in the above given codes none did compile itself ......u had written ....
    "This source code, in turn, should compile and print out itself"
    Hi sumit,

    Our codes are well compiled and tested.Can you show us what compiler errors you are getting and which version of java you are using?This info. will be of great help to us in helping you . 😀
  • Ashutosh_shukla
    Ashutosh_shukla
    Sumit, The program if it wants the source code once only is given by me in C. If you want that the process should happen n number of times then write the printing part as a function and call in a loop. If you want it to contiue infinitely then in an infinite loop you can call the function that reads the file and prints it.For user interaction you may ask him whethar he wants to continue and then only call the function otherwise break and program execution.
    😁
  • sumitjami
    sumitjami
  • cyberhack
    cyberhack
    Another way to write self printing program is reading a file ,which is itself, and write print this file. This is the source code:

    //file name is readitself.c
    #include
    #include
    int main( ){
    FILE *source ;
    int read;
    source = fopen("readd.c", "r") ;

    while(!feof(read = fgetc(source))){
    putchar(read);
    } //end of while
    fclose(source);
    return 0;
    } //end of main
  • cyberhack
    cyberhack
    sorry
    source = fopen("readd.c", "r") ; --> this part is wrong
    you shuld write source = fopen("readitself.c", "r") ;
  • disaster
    disaster
    can any say how to write this program
    123454321
    1234..4321
    123.....321
    12........21
    1...........1
  • Ashutosh_shukla
    Ashutosh_shukla
    Can you please complete your homeworks on your own and please at least try once and then post the doubt,
    Hey CEans i am back after a lay off
  • pradeep_agrawal
    pradeep_agrawal
    I feel the actual problem statement is not just to read from a file and output the contents. That code will be dependent on the file containing actual source code.

    The problem statement is to write a program that prints itself, and the program should work even on the machine where the file containing actual source code is not present.

    -Pradeep
  • slashfear
    slashfear
    Hey guys,

    @pradeep, yes dude the program should print itself, it should not read the content from another file ;-)

    Thanks bigie for the challenge...............😁

    Little info about the program: A self printing program is called as QUINE. (for those who doesn't know 😉)

    Here is my solution (really broke my head 😡)

    [B]#include 
    
    int main (void)
    {
      char *s1="#include %c%cint%cmain (void)%c{%c";
      char *s2="  char *s%c=%c%s%c;%c  char *s%c=%c%s%c;%c";
      char *s3="  char n='%cn', q='%c', b='%c%c';%c";
      char *sp="  printf(";
      char *s4="%ss1,n,n,n,n,n);%c";
      char *s5="%ss2,'1',q,s1,q,n,'2',q,s2,q,n);%ss2,'3',q,s3,q,n,'p',q,sp,q,n);%c";
      char *s6="%ss2,'4',q,s4,q,n,'5',q,s5,q,n);%ss2,'6',q,s6,q,n,'7',q,s7,q,n);%c";
      char *s7="%ss2,'8',q,s8,q,n,'9',q,s9,q,n);%ss2,'0',q,s0,q,n,'x',q,sx,q,n);%c";
      char *s8="%ss3,b,q,b,b,n);%ss4,sp,n);%ss5,sp,sp,n);%c";
      char *s9="%ss6,sp,sp,n);%ss7,sp,sp,n);%ss8,sp,sp,sp,n);%c";
      char *s0="%ss9,sp,sp,sp,n);%ss0,sp,sp,n,n,n);%c  return 0;%c}%c";
      char *sx="--- This is an intron. ---";
      char n='\n', q='"', b='\\';
      printf(s1,n,n,n,n,n);
      printf(s2,'1',q,s1,q,n,'2',q,s2,q,n);  printf(s2,'3',q,s3,q,n,'p',q,sp,q,n);
      printf(s2,'4',q,s4,q,n,'5',q,s5,q,n);  printf(s2,'6',q,s6,q,n,'7',q,s7,q,n);
      printf(s2,'8',q,s8,q,n,'9',q,s9,q,n);  printf(s2,'0',q,s0,q,n,'x',q,sx,q,n);
      printf(s3,b,q,b,b,n);  printf(s4,sp,n);  printf(s5,sp,sp,n);
      printf(s6,sp,sp,n);  printf(s7,sp,sp,n);  printf(s8,sp,sp,sp,n);
      printf(s9,sp,sp,sp,n);  printf(s0,sp,sp,n,n,n);
      return 0;
    }[/B]
     
    Hope the Mission is accomplished

    PS: Hey pradeep check my code and give any suggetions buddy..... :smile: (I love your suggestions dude!!!) if any changes tell me buddy


    -Arvind(slashfear)
  • silverscorpion
    silverscorpion
    awesome dude!! 😀

    Could you also explain the program?? How does it work?

    Specifically, how do the printf statements work without the format specifier??

    And what purpose does "char *sx" serve? It's not used anywhere.

    You rock dude!! 😀
  • pradeep_agrawal
    pradeep_agrawal
    That's really cool buddy, a perfect example of work of genius.

    A person can comment on a code when he has something better to offer. And after looking into your code currently i don't have anything to add, so no comments buddy. 😀

    -Pradeep
  • rama_krish627
    rama_krish627
    I compiled and executed the above program successfully.
    Intially it shows some errors that conio.h is not found and clrscr() not in this scope. but finally after removing these i got the output.
  • pradeep_agrawal
    pradeep_agrawal
    rama_krish627
    I compiled and executed the above program successfully.
    Intially it shows some errors that conio.h is not found and clrscr() not in this scope. but finally after removing these i got the output.
    Exactly which code you are referring to? I am sure it's not the latest code posted by Slashfear at

    #-Link-Snipped-#

    because the Slashfear's code does not include file conio.h.

    -Pradeep
  • slashfear
    slashfear
    Hi Scorpion,

    PS: Sorry for the late reply, I was kinnda busy, so dint check out CE....... sorry dude!!

    The basic idea is this:

    It is impossible (in most programming languages) for a program to manipulate itself (i.e. its textual representation — or a representation from which its textual representation can be easily derived) directly.

    So to make this possible anyway, we write the build the program from two parts, one which call the code and one which we call the data. The data represents (the textual form of) the code, and it is derived in an algorithmic way from it. The code uses the data to print the code (which is easy because the data represents the code); then it uses the data to print the data (which is possible because the data is obtained by an algorithmic transformation from the code).

    I choose C because it is widely known, and also because the printf() function has features which will make writing a quine considerably easier (this is a mixed blessing: it is a gain because it makes the quine smaller, but it also makes it sensibly more obscure and “hackish”).

    We will want the quine to be correct C code, so it will probably have to begin something like this:
    #include 
    
    int
    main (void)
    {
    
    The first thing I want to do is print all what precedes. Naively, we could write:
      printf("#include \n\nint\nmain (void)\n{\n");
    
    Then I need to print this line itself:
      printf("printf(\"#include \\n\\nint\\nmain (void)\\n{\\n\");\n");
    
    And so on. It should be obvious that this is not going to work (except if we intend to produce a quine of infinite length, which we do not).

    This is the sort of reasoning which makes some people believe that quines don't exist. The problem is that we need to print something, so we use a character string (say s) to print it, and then we need to print s itself, so we use another character string, and so on…

    If we intend to print s, we don't need another string: we can use s itself. So I modified and give it another try:
      char *s="#include \n\nint\nmain (void)\n{\n";
      printf(s);  printf("char *s=\"%s\";\n",s);
    
    Well, it still doesn't work. But we have introduced one of the central ideas in quine-writing lore: whereas it is probably necessary to use some data to represent the code to be printed, on the other hand it is possible to reuse these data to print the data themselves. Here we're still a bit naive: we're using s “as it stands”, but that won't work because it contains some backslashes; these would need to be further backslashified. So the King's way is to proceed with backslashification, which will work because this is a computable process. However, since we are writing in C, we choose a shortcut which uses the nice properties of the printf function:
      char *s1="#include %c%cint%cmain (void)%c{%c";
      char *s2="  char *s1=%c%s%c;%c  char *s2=%c%s%c;%c";
      char n='\n', q='"';
      printf(s1,n,n,n,n,n);
      printf(s2,q,s1,q,n,q,s2,q,n);
    
    This is a partial quine: it prints the beginning of its own listing (something in no way remarkable, since any program which doesn't print anything is a “partial quine”). Here we have passed the “catching up point”, by this I mean that the program data printed includes the data representation itself. It is then generally trivial to complete the quine and some of the data are actually hidden in the printf() statements. Nevertheless, it is not very difficult to finish, So finally I ended up like this:
    #include 
    
    int
    main (void)
    {
      char *s1="#include %c%cint%cmain (void)%c{%c";
      char *s2="  char *s%c=%c%s%c;%c  char *s%c=%c%s%c;%c";
      char *s3="  char n='%cn', q='%c', b='%c%c';%c";
      char *sp="  printf(";
      char *s4="%ss1,n,n,n,n,n);%c";
      char *s5="%ss2,'1',q,s1,q,n,'2',q,s2,q,n);%ss2,'3',q,s3,q,n,'p',q,sp,q,n);%c";
      char *s6="%ss2,'4',q,s4,q,n,'5',q,s5,q,n);%ss2,'6',q,s6,q,n,'7',q,s7,q,n);%c";
      char *s7="%ss2,'8',q,s8,q,n,'9',q,s9,q,n);%ss2,'0',q,s0,q,n,'x',q,sx,q,n);%c";
      char *s8="%ss3,b,q,b,b,n);%ss4,sp,n);%ss5,sp,sp,n);%c";
      char *s9="%ss6,sp,sp,n);%ss7,sp,sp,n);%ss8,sp,sp,sp,n);%c";
      char *s0="%ss9,sp,sp,sp,n);%ss0,sp,sp,n,n,n);%c  return 0;%c}%c";
      char *sx="--- This is an intron. ---";
      char n='\n', q='"', b='\\';
      printf(s1,n,n,n,n,n);
      printf(s2,'1',q,s1,q,n,'2',q,s2,q,n);  printf(s2,'3',q,s3,q,n,'p',q,sp,q,n);
      printf(s2,'4',q,s4,q,n,'5',q,s5,q,n);  printf(s2,'6',q,s6,q,n,'7',q,s7,q,n);
      printf(s2,'8',q,s8,q,n,'9',q,s9,q,n);  printf(s2,'0',q,s0,q,n,'x',q,sx,q,n);
      printf(s3,b,q,b,b,n);  printf(s4,sp,n);  printf(s5,sp,sp,n);
      printf(s6,sp,sp,n);  printf(s7,sp,sp,n);  printf(s8,sp,sp,sp,n);
      printf(s9,sp,sp,sp,n);  printf(s0,sp,sp,n,n,n);
      return 0;
    }
    
    Here we have a real quine. Note the use of the s2 string to print several lines modeled on the same pattern. Also note how the backslash required no special treatment. And note the sx string which goes to show that the classical belief that everything in a quine must be doubled, is false.

    however, to the fact that I should have written “const char *” rather than just “char *”; this is much better than many quines which omit the return 0 at the end or similar things.

    Hope you understood buddy!!!😒

    PS: Thanks Pradeep!!!!!!😁

    -Arvind(slashfear)
  • silverscorpion
    silverscorpion
    Wow. Now I understand.. Brilliant. Definitely work of a genius..

    Thanks for the explanation. 😀
  • Saandeep Sreerambatla
    Saandeep Sreerambatla
    Its really tooooooooooooomuch excellent work Shash fear .
    You are a real genius 😀
  • Ashraf HZ
    Ashraf HZ
    slashfear
    Hi Scorpion,

    PS: Sorry for the late reply, I was kinnda busy, so dint check out CE....... sorry dude!!

    The basic idea is this:

    It is impossible (in most programming languages) for a program to manipulate itself (i.e. its textual representation — or a representation from which its textual representation can be easily derived) directly.

    So to make this possible anyway, we write the build the program from two parts, one which call the code and one which we call the data. The data represents (the textual form of) the code, and it is derived in an algorithmic way from it. The code uses the data to print the code (which is easy because the data represents the code); then it uses the data to print the data (which is possible because the data is obtained by an algorithmic transformation from the code).

    I choose C because it is widely known, and also because the printf() function has features which will make writing a quine considerably easier (this is a mixed blessing: it is a gain because it makes the quine smaller, but it also makes it sensibly more obscure and “hackish”).

    We will want the quine to be correct C code, so it will probably have to begin something like this:
    #include 
    
    int
    main (void)
    {
    
    The first thing I want to do is print all what precedes. Naively, we could write:
      printf("#include \n\nint\nmain (void)\n{\n");
    
    Then I need to print this line itself:
      printf("printf(\"#include \\n\\nint\\nmain (void)\\n{\\n\");\n");
    
    And so on. It should be obvious that this is not going to work (except if we intend to produce a quine of infinite length, which we do not).

    This is the sort of reasoning which makes some people believe that quines don't exist. The problem is that we need to print something, so we use a character string (say s) to print it, and then we need to print s itself, so we use another character string, and so on…

    If we intend to print s, we don't need another string: we can use s itself. So I modified and give it another try:
      char *s="#include \n\nint\nmain (void)\n{\n";
      printf(s);  printf("char *s=\"%s\";\n",s);
    
    Well, it still doesn't work. But we have introduced one of the central ideas in quine-writing lore: whereas it is probably necessary to use some data to represent the code to be printed, on the other hand it is possible to reuse these data to print the data themselves. Here we're still a bit naive: we're using s “as it stands”, but that won't work because it contains some backslashes; these would need to be further backslashified. So the King's way is to proceed with backslashification, which will work because this is a computable process. However, since we are writing in C, we choose a shortcut which uses the nice properties of the printf function:
      char *s1="#include %c%cint%cmain (void)%c{%c";
      char *s2="  char *s1=%c%s%c;%c  char *s2=%c%s%c;%c";
      char n='\n', q='"';
      printf(s1,n,n,n,n,n);
      printf(s2,q,s1,q,n,q,s2,q,n);
    
    This is a partial quine: it prints the beginning of its own listing (something in no way remarkable, since any program which doesn't print anything is a “partial quine”). Here we have passed the “catching up point”, by this I mean that the program data printed includes the data representation itself. It is then generally trivial to complete the quine and some of the data are actually hidden in the printf() statements. Nevertheless, it is not very difficult to finish, So finally I ended up like this:
    #include 
    
    int
    main (void)
    {
      char *s1="#include %c%cint%cmain (void)%c{%c";
      char *s2="  char *s%c=%c%s%c;%c  char *s%c=%c%s%c;%c";
      char *s3="  char n='%cn', q='%c', b='%c%c';%c";
      char *sp="  printf(";
      char *s4="%ss1,n,n,n,n,n);%c";
      char *s5="%ss2,'1',q,s1,q,n,'2',q,s2,q,n);%ss2,'3',q,s3,q,n,'p',q,sp,q,n);%c";
      char *s6="%ss2,'4',q,s4,q,n,'5',q,s5,q,n);%ss2,'6',q,s6,q,n,'7',q,s7,q,n);%c";
      char *s7="%ss2,'8',q,s8,q,n,'9',q,s9,q,n);%ss2,'0',q,s0,q,n,'x',q,sx,q,n);%c";
      char *s8="%ss3,b,q,b,b,n);%ss4,sp,n);%ss5,sp,sp,n);%c";
      char *s9="%ss6,sp,sp,n);%ss7,sp,sp,n);%ss8,sp,sp,sp,n);%c";
      char *s0="%ss9,sp,sp,sp,n);%ss0,sp,sp,n,n,n);%c  return 0;%c}%c";
      char *sx="--- This is an intron. ---";
      char n='\n', q='"', b='\\';
      printf(s1,n,n,n,n,n);
      printf(s2,'1',q,s1,q,n,'2',q,s2,q,n);  printf(s2,'3',q,s3,q,n,'p',q,sp,q,n);
      printf(s2,'4',q,s4,q,n,'5',q,s5,q,n);  printf(s2,'6',q,s6,q,n,'7',q,s7,q,n);
      printf(s2,'8',q,s8,q,n,'9',q,s9,q,n);  printf(s2,'0',q,s0,q,n,'x',q,sx,q,n);
      printf(s3,b,q,b,b,n);  printf(s4,sp,n);  printf(s5,sp,sp,n);
      printf(s6,sp,sp,n);  printf(s7,sp,sp,n);  printf(s8,sp,sp,sp,n);
      printf(s9,sp,sp,sp,n);  printf(s0,sp,sp,n,n,n);
      return 0;
    }
    
    Here we have a real quine. Note the use of the s2 string to print several lines modeled on the same pattern. Also note how the backslash required no special treatment. And note the sx string which goes to show that the classical belief that everything in a quine must be doubled, is false.

    however, to the fact that I should have written “const char *” rather than just “char *”; this is much better than many quines which omit the return 0 at the end or similar things.

    Hope you understood buddy!!!😒

    PS: Thanks Pradeep!!!!!!😁

    -Arvind(slashfear)
    Slashfear, are you sure these are in your own words? I found a near replicate of this explanation in this website:
    #-Link-Snipped-#

    Please remember that it is very important to put references if you have used original material from somewhere else!
  • shalini_goel14
    shalini_goel14
    Yo ! Ash you rock in googling.😁 We are proud to have you on CE. I was suspecting same kind of thing that's why stopped praising this guy anymore. 😉
  • Kaustubh Katdare
    Kaustubh Katdare
    We strongly recommend against copying content from other websites. If you 'must' do so, please mention the source.

You are reading an archived discussion.

Related Posts

CEans, We've lot of members who are studying in colleges. I remember, when I was in college, I used to discuss the question paper with my friends to figure out...
hello can any one help me in doin my project in robotics
How can I crack a software?... How can I make patches for shareware software to make them permanent? can anyone help me?
DWDM.zip RapidShare: Easy Filehosting Size:9317 KB
hey .. here i am creating this thread for all the interested sponsors in tech fests and other activities in various colleges and university,,, any body interested can ask about...