[雑談]自分自身を出力するプログラム

フォーラム(掲示板)ルール
フォーラム(掲示板)ルールはこちら  ※コードを貼り付ける場合は [code][/code] で囲って下さい。詳しくはこちら
組木紙織

[雑談]自分自身を出力するプログラム

#1

投稿記事 by 組木紙織 » 15年前

Haskellで自分自身を出力するプログラムを書いてみようをいう記事
ttp://www.ipsj.or.jp/07editj/promenade/4703.pdf
をみつけたので、
C++自分自身を出力するプログラムを書いてみました。
なかなか難しくて、ごてごでした力ずくで書いた感じのコードになってしまいました。

ほかの人の書いたコードをみてみたいと思い投稿しました。

条件はC/C++で、コンパイラのエラーがでない程度のコード。
最低限インクルードを入れてください。

色々な方法で作ったコードを待ってます。
#include <iostream>
char*a="\n";char*b="\0";char*c="\\";char*d="\"";char*e="\\0";char*ch="#include <iostream>\0char*a=\0n\0;char*b=\0 0\0;char*c=\0;char*d=\0;char*e=\0;char*ch=\0;int main(){std::cout<<ch<<a<<&ch[20]<<d<<c<<&ch[28]<<d<<&ch[30]<<d<<c<<&ch[40]<<d<<&ch[42]<<d<<c<<c<<d<<&ch[51]<<d<<c<<d<<d<<&ch[60]<<d<<c<<c<<&ch[40]<<d<<&ch[69]<<d<<ch<<e<<&ch[20]<<e<<&ch[28]<<e<<&ch[30]<<e<<&ch[39]<<e<<&ch[42]<<e<<&ch[51]<<e<<&ch[60]<<e<<&ch[69]<<e<<&ch[79]<<d<<&ch[79]<<std::endl;return 0;}";int main(){std::cout<<ch<<a<<&ch[20]<<d<<c<<&ch[28]<<d<<&ch[30]<<d<<c<<&ch[40]<<d<<&ch[42]<<d<<c<<c<<d<<&ch[51]<<d<<c<<d<<d<<&ch[60]<<d<<c<<c<<&ch[40]<<d<<&ch[69]<<d<<ch<<e<<&ch[20]<<e<<&ch[28]<<e<<&ch[30]<<e<<&ch[39]<<e<<&ch[42]<<e<<&ch[51]<<e<<&ch[60]<<e<<&ch[69]<<e<<&ch[79]<<d<<&ch[79]<<std::endl;return 0;}

Naohiro19

Re:[雑談]自分自身を出力するプログラム

#2

投稿記事 by Naohiro19 » 15年前

Line 19: error: iostream: No such file or directory
In function 'main':
Line 2: error: expected expression before ':' token

組木紙織

Re:[雑談]自分自身を出力するプログラム

#3

投稿記事 by 組木紙織 » 15年前

Naohiro19さん

c言語でコンパイルしていませんか?
c++でコンパイルしてみてください。

御津凪

Re:[雑談]自分自身を出力するプログラム

#4

投稿記事 by 御津凪 » 15年前

興味があったのでCでやってみました。
#include <stdio.h>
char* q = "#include <stdio.h>\nchar* q = %;\nint p = 1;\nvoid wq( void ){\n\tchar* r = q;\n\twhile(*r != 0){\n\t\tif(*r == 9) printf('%ct', 92);\n\t\telse if(*r == 10) printf('%cn', 92);\n\t\telse putchar(*r);\n\t\t++r;\n\t}\n\tp = 0;\n}\nint main( void ){\n\tchar* r = q;\n\twhile(*r != 0){\n\t\tif(*r == 37){ if(p){ putchar(34); wq(); putchar(34); } else putchar(*r); }\n\t\telse if(*r == 39) putchar(34);\n\t\telse putchar(*r);\n\t\t++r;\n\t}\n\treturn 0;\n}\n";
int p = 1;
void wq( void ){
	char* r = q;
	while(*r != 0){
		if(*r == 9) printf("%ct", 92);
		else if(*r == 10) printf("%cn", 92);
		else putchar(*r);
		++r;
	}
	p = 0;
}
int main( void ){
	char* r = q;
	while(*r != 0){
		if(*r == 37){ if(p){ putchar(34); wq(); putchar(34); } else putchar(*r); }
		else if(*r == 39) putchar(34);
		else putchar(*r);
		++r;
	}
	return 0;
}
ふと思いついた方法は提示されていた記事内で書かれていたものだったので、
while 関数を使って文字列の置き換えをしたり関数を使ってたりしてます。

こうやって見ると結構頭を使いますね。

Eeel

Re:[雑談]自分自身を出力するプログラム

#5

投稿記事 by Eeel » 15年前

力技です。
タブと改行を含めて表示し、横に長い文字列を使わない事を目標にしたら
こんな事になってしまいました。
#include <stdio.h>

char d = 0x22;
char n = 0x0A;
char t = 0x09;

int main()
{
	char *str[7] = {"#include <stdio.h>","char d = 0x22;","char n = 0x0A;","char t = 0x09;","int main()","{","char *str[7] = {"};
	char *str2[5] = {"%s%c%c%s%c%s%c%s%c%c%s%c%s%c%c%s",
					"%c%s%c,%c%s%c,%c%s%c,%c%s%c,%c%s%c,%c%s%c,%c%s%c};%c",
					"%cchar *str2[5] = {%c%s%c,%c%c%c%c%c%c%c%s%c,%c%c%c%c%c%c%c%s%c,%c%c%c%c%c%c%c%s%c,%c%c%c%c%c%c%c%s%c};%c",
					"%cchar *str3[5] = {%c%s%c,%c%c%c%c%c%c%c%s%c,%c%c%c%c%c%c%c%s%c,%c%c%c%c%c%c%c%s%c,%c%c%c%c%c%c%c%s%c};%c%c",
					"%cprintf(%c%s%c,%s);%c%cprintf(%c%s%c,%s);%c%cprintf(%c%s%c,%c%c%c%s);%c%cprintf(%c%s%c,%c%c%c%s);%c%cprintf(%c%s%c,%c%c%c%s);%c}"};
	char *str3[5] = {"str[0],n,n,str[1],n,str[2],n,str[3],n,n,str[4],n,str[5],n,t,str[6]",
					"d,str[0],d,d,str[1],d,d,str[2],d,d,str[3],d,d,str[4],d,d,str[5],d,d,str[6],d,n",
					"t,d,str2[0],d,n,t,t,t,t,t,d,str2[1],d,n,t,t,t,t,t,d,str2[2],d,n,t,t,t,t,t,d,str2[3],d,n,t,t,t,t,t,d,str2[4],d,n",
					"t,d,str3[0],d,n,t,t,t,t,t,d,str3[1],d,n,t,t,t,t,t,d,str3[2],d,n,t,t,t,t,t,d,str3[3],d,n,t,t,t,t,t,d,str3[4],d,n,n",
					"t,d,str2[0],d,str3[0],n,t,d,str2[1],d,str3[1],n,t,d,str2[2],d,n,t,t,str3[2],n,t,d,str2[3],d,n,t,t,str3[3],n,t,d,str2[4],d,n,t,t,str3[4],n"};

	printf("%s%c%c%s%c%s%c%s%c%c%s%c%s%c%c%s",str[0],n,n,str[1],n,str[2],n,str[3],n,n,str[4],n,str[5],n,t,str[6]);
	printf("%c%s%c,%c%s%c,%c%s%c,%c%s%c,%c%s%c,%c%s%c,%c%s%c};%c",d,str[0],d,d,str[1],d,d,str[2],d,d,str[3],d,d,str[4],d,d,str[5],d,d,str[6],d,n);
	printf("%cchar *str2[5] = {%c%s%c,%c%c%c%c%c%c%c%s%c,%c%c%c%c%c%c%c%s%c,%c%c%c%c%c%c%c%s%c,%c%c%c%c%c%c%c%s%c};%c",
		t,d,str2[0],d,n,t,t,t,t,t,d,str2[1],d,n,t,t,t,t,t,d,str2[2],d,n,t,t,t,t,t,d,str2[3],d,n,t,t,t,t,t,d,str2[4],d,n);
	printf("%cchar *str3[5] = {%c%s%c,%c%c%c%c%c%c%c%s%c,%c%c%c%c%c%c%c%s%c,%c%c%c%c%c%c%c%s%c,%c%c%c%c%c%c%c%s%c};%c%c",
		t,d,str3[0],d,n,t,t,t,t,t,d,str3[1],d,n,t,t,t,t,t,d,str3[2],d,n,t,t,t,t,t,d,str3[3],d,n,t,t,t,t,t,d,str3[4],d,n,n);
	printf("%cprintf(%c%s%c,%s);%c%cprintf(%c%s%c,%s);%c%cprintf(%c%s%c,%c%c%c%s);%c%cprintf(%c%s%c,%c%c%c%s);%c%cprintf(%c%s%c,%c%c%c%s);%c}",
		t,d,str2[0],d,str3[0],n,t,d,str2[1],d,str3[1],n,t,d,str2[2],d,n,t,t,str3[2],n,t,d,str2[3],d,n,t,t,str3[3],n,t,d,str2[4],d,n,t,t,str3[4],n);
}

hoge

Re:[雑談]自分自身を出力するプログラム

#6

投稿記事 by hoge » 15年前

HD内に昔作ったものがありました。
#include <stdio.h>
#define A(X) B(X)
#define B(X) #X
#define C int main(){puts(D A(D)"\nC");return 0;}
#define D "#include <stdio.h>\n#define A(X) B(X)\n#define B(X) #X\n#define C int main(){puts(D A(D)\"\\nC\");return 0;}\n#define D "
C
(注)VC6以前だとコンパイラのバグのためコンパイルできません。

たかぎ

Re:[雑談]自分自身を出力するプログラム

#7

投稿記事 by たかぎ » 15年前

まるっきりのネタですが...
#include <iostream>
#include <fstream>

int main()
{
	std::ifstream ifs(__FILE__);
	std::cout << ifs.rdbuf();
}
こんなのはどうでしょう?

組木紙織

Re:[雑談]自分自身を出力するプログラム

#8

投稿記事 by 組木紙織 » 15年前

>御津凪さん
ふむふむなるほどっといった感じのコードですね。
char型は一応文字型であるが数値型としても使えるというc言語の特徴を生かしたコードですね。

>Eeelさん
私と似たような力づくのコード。
力づくのコードは同じ出力にするための微調節が大変ですよね。

>hogeさん
Cマクロにはこんな使い方があるとは知りませんでした。
こんな使い方はトリッキーになるのかな。
ちょっと使い方覚えてみたくなりました。

>たかぎさん
それはネタというより地雷です。
隠れ条件としてそのような方法はだめと決めてました。
(引っかかってくれてなんか嬉しい)

リンク先の記事を読んだら最初のほうにちゃんと書いてあります。

たかぎ

Re:[雑談]自分自身を出力するプログラム

#9

投稿記事 by たかぎ » 15年前

> リンク先の記事を読んだら最初のほうにちゃんと書いてあります。

本当ですね。
最近はちゃんとしたリンク以外読まないので...
面倒なのもありますが、ちゃんとリンクを貼れないのは何か後ろめたい理由があるのではとかんぐってしまいます。

組木紙織

Re:[雑談]自分自身を出力するプログラム

#10

投稿記事 by 組木紙織 » 15年前

>面倒なのもありますが、ちゃんとリンクを貼れないのは何か後ろめたい理由があるのではとかんぐってしまいます。

ちゃんとリンクを貼ってなかったのはそのように考えられてしまいましたか。すみません。
今回のリンク先はpdfなので、何気なく開くと時間がかかるんですよね。
何気なく開いて、開くまでの時間にイライラしてもらうよりは、気合い(?)を入れて開いてもらったほうがよいかと。

Naohiro19

Re:[雑談]自分自身を出力するプログラム

#11

投稿記事 by Naohiro19 » 15年前

/*test.c*/
#include <stdio.h>

int main()
{
    FILE* fp = fopen("test.c", "rb");
    char ch;
    while(!feof(fp)){
        ch = fread(ch, sizeof(char), 1, fp);
        printf("%c", ch);
    }
    fclose(fp);
    return 0;
}
標準関数のみで作ってみました

組木紙織

Re:[雑談]自分自身を出力するプログラム

#12

投稿記事 by 組木紙織 » 15年前

>Naohiro19さん
だからそれは地雷なんですって。
それは別にいいですけど、もう少しひねって欲しかったです。
無意味に複雑な処理を入れるとか、よみにくくするとか。。。

たいちう

Re:[雑談]自分自身を出力するプログラム

#13

投稿記事 by たいちう » 15年前

昔見かけた記憶があったので探してみた。

http://www.kouno.jp/home/c_faq/c20.html#0
後半の"20.34"の部分に書かれている。

閉鎖

“C言語何でも質問掲示板” へ戻る