http://www.pronix.de -> Forum -> Knobelecke

Forum: Knobelecke

Moderatoren: broesel, juergen

Thema: Ausgabe des eigenen Quelltexts

Ausgabe des eigenen Quelltexts

broesel (webmaster) am 15.07.2004 um 12:50

Gesucht ist ein C-Programm, dass seinen eigenen Quelltext ausgibt.

Natürlich soll das Programm seinen Quelltext nicht aus einer Datei lesen. Die beiden Versionen (der Original-Quelltext und die Ausgabe des Programms) dürfen sich nicht unterscheiden. Googeln gilt nicht.

Gruss
Philip

PS: Wer schonmal ein solches Programm geschrieben hat, hier der zweite Schwierigkeitsgrad: schreibe ein C-Programm, dass den Quelltext eines Perl-Script ausgibt, dass den Quelltext des C-Programms ausgibt, dass den Quelltext des Perl-Scripts ausgibt usw.

PPS: Solche Programme kann man in jeder Sprache schreiben, die sich Turing-complete schimpft, also auch beispielsweise Brainfuck (siehe http://e.a.la/code/a2bf/index.shtml (externer link) ). Wer kann in Brainfuck ein Programm schreiben, dass seinen eigenen Quelltext ausgibt? (Ich nicht...)

--
The C Programming Quiz (externer link) - bitte Fragen einreichen :)

 

Ausgabe des eigenen Quelltexts

juergen (webmaster) am 16.07.2004 um 06:59

... ich versuche hierzu auch mal einen Tipp zur weiteren Recherche anzugeben, da das Rätsel doch etwas schwerer zu sein scheint.

Stichwort "Quines" Grafik: Smilie Zwinker

Gruss
Jürgen

@broesel: Ich hoffe ich oute mich jetzt nicht als Spielverderber - aber das Rätsel hat es in sich
 

Ausgabe des eigenen Quelltexts

jengelh am 16.07.2004 um 12:10

Hah ich glaub ich habs:

#include <sys/stat.h>
#include <sys/types.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>

#ifndef FILENO_STDOUT
#    define FILENO_STDOUT fileno(stdout)
#endif

int main(void) {
    int fd = open(__FILE__, O_RDONLY);
    char buf[1024];
    int eax;

    while((eax = read(fd, buf, 1024)) > 0) {
        write(FILENO_STDOUT, buf, eax);
    }

    return EXIT_SUCCESS;
}

Umgeht zwar "aus einer Datei lesen", aber trifft ansonsten das Rätsel 8-)
Hier noch eins:

#include <stdio.h>
#include <unistd.h>

int main(int argc, char **argv) {
    char buf[1024];
    snprintf(buf, 1024, "objdump -D \"%s\"", *argv);
    return system(buf);
}

Grafik: Smilie Lachend
Obwohl... seinen eigenen Code auszudrucken noch einfacher wäre:

#include <stdio.h>

int main(void) {
    FILE *fp = fopen("/proc/self/maps", "r");
    char buf[1024];

    if(fgets(buf, 1024, fp) != NULL) {
        char *start = buf, *end;
        unsigned long sa, ea;
        const char *i;

        end = strchr(buf, '-');
        *end++ = '\0';
        sa = strtoul(start, NULL, 0);
        ea = strtoul(end, NULL, 0);

        i = (const char *)sa;
        while(i < (const char *)ea) { putc(*i++); }
    }
    return EXIT_SUCCESS;
}

Untested, aber should work.
 

Ausgabe des eigenen Quelltexts

juergen (webmaster) am 16.07.2004 um 12:50

... war ja klar, dass Dir hierzu wieder etwas anderes einfällt Grafik: Smilie Zwinker - "gewöhnlich" kennst Du ja nicht Grafik: Smilie Lachend

Eine weitere Lösung hierzu wären, wie erwähnt sogenannte Quines ("self-reproducing programs") - wie dies etwa beim erstellen von Viren und Würmern verwendet werden kann (wenn ein Virus eine Kopie von sich selbst machen kann). Also ein Listing der Art:

char *f="char *f=%c%s%c;%c#define Q '%c'%c#define N '%cn'%c#define B '%c%c'%c"
     "#include <stdio.h>%cint main(){printf(f,Q,f,Q,N,Q,N,B,N,B,B,N,N,N);}%c";
#define Q '"'
#define N '\n'
#define B '\\'
#include <stdio.h>
int main(){printf(f,Q,f,Q,N,Q,N,B,N,B,B,N,N,N);}


Mehr dazu findet man hier (insklusive weiterer Links):
http://www.eleves.ens.fr:8080/home/madore/computers/quine.html

Gruss
Jürgen
 

Ausgabe des eigenen Quelltexts

broesel (webmaster) am 16.07.2004 um 15:41

Hirogen's Lösungen sind zwar teilweise interessant, erfüllen aber nicht die Aufgabenstellung (seinen eigenen Quelltext ohne das Öffnen von Dateien auszugeben).

Jürgen hat's geschafft, ein echtes Quine zu schreiben, und ist somit qualifiziert, einen Hybrid zu schreiben:
Ein C-Programm, dass den Quelltext eines Perl-Programms ausgibt, dass den Quelltext des ursprünglichen C-Programms ausgibt. *evilgrin*

Quines kann man übrigens in jeder Sprache schreiben, die sich Turing-Complete schimpft.
Assembler beispielsweise.
Emacs Lisp.
TECO Script.
M4 Macro.
Brainfuck.
...um nur ein paar der interessanteren Sprachen zu erwähnen ;))

Ich poste mal meine Lösung, wenn ich wieder zuhause bin. Die ist zwar länger, hat aber den Vorteil dass der Datenteil nur aus einer Variable besteht. Man kann leichter unterschiedliche Ausgaben erzeugen.

Gruss
Philip

--
The C Programming Quiz (externer link) - bitte Fragen einreichen :)