Forum: Knobelecke
Moderatoren: broesel, juergenThema: Ausgabe des eigenen Quelltexts
Ausgabe des eigenen Quelltexts
broesel (webmaster) am 15.07.2004 um 12:50
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
). Wer kann in Brainfuck ein Programm schreiben, dass seinen eigenen Quelltext ausgibt? (Ich nicht...)
--
The C Programming Quiz
- bitte Fragen einreichen :)
Ausgabe des eigenen Quelltexts
juergen (webmaster) am 16.07.2004 um 06:59
Stichwort "Quines"
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
#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);
}
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
- "gewöhnlich" kennst Du ja nicht
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
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
- bitte Fragen einreichen :)
