C++11でBrainf*ck【Better C】

#Brainf*ckとは

以下の命令によって動く言語です。

> 1. `>` ポインタをインクリメントする。ポインタをptrとすると、C言語の「`ptr++;`」に相当する。
> 2. `<` ポインタをデクリメントする。C言語の「`ptr--;`」に相当。
> 3. `+` ポインタが指す値をインクリメントする。C言語の「`(*ptr)++;`」に相当。
> 4. `-` ポインタが指す値をデクリメントする。C言語の「`(*ptr)--;`」に相当。
> 5. `.` ポインタが指す値を出力に書き出す。C言語の「`putchar(*ptr);`」に相当。
> 6. `,` 入力から1バイト読み込んで、ポインタが指す先に代入する。C言語の「`*ptr=getchar();`」に相当。
> 7. `[` ポインタが指す値が0なら、対応する `]` の直後にジャンプする。C言語の「`while(*ptr){`」に相当。
> 8. `]` ポインタが指す値が0でないなら、対応する `[` （の直後[1]）にジャンプする。C言語の「`}`」に相当[2]。
>(引用: Wikipedia [Brainfuck](https://ja.wikipedia.org/wiki/Brainfuck))

使用する命令が8個しかないのが非常に特徴的ですね。
では、実装していきましょう。

#ソースコード(Visual C++)
```cpp:Source.cpp
#include <cstdio>
#include <cstdint>
#include <string>

int main(int argc, char *argv[])
{
	//ファイルが指定されていない時のエラー処理
	if (argc != 2) {
		std::printf("開くファイルを指定してください。\n");
		return -1;
	}
	//ファイルが開けない時のエラー処理
	std::FILE *fp = nullptr;
	if (fopen_s(&fp, argv[1], "r")) {
		std::printf("ファイルを開くことが出来ません。\n");
		return -1;
	}

	//コードを読み取って格納
	char read_char;
	std::string code{};
	while ((read_char = std::fgetc(fp)) != EOF) {
		code.push_back(read_char);
	}
	std::fclose(fp);

	//コードを処理
	constexpr std::size_t buffer_size = 30000;
	char buffer[buffer_size]{};
	std::size_t buffer_ptr = 0;
	std::int_fast32_t loop = 0;

	const std::size_t code_len = code.size();
	for (std::size_t code_ptr = 0; code_ptr < code_len; ++code_ptr) {

		switch (code[code_ptr]) {
		case '>':++buffer_ptr; break;
		case '<':--buffer_ptr; break;
		case '+':++buffer[buffer_ptr]; break;
		case '-':--buffer[buffer_ptr]; break;
		case '.':std::putchar(buffer[buffer_ptr]); break;
		case ',':buffer[buffer_ptr] = std::getchar(); break;
		case '[':
			if (buffer[buffer_ptr] != 0) break;
			for (++code_ptr; loop > 0 || code[code_ptr] != ']'; ++code_ptr) {
				if (code[code_ptr] == '[') ++loop;
				if (code[code_ptr] == ']') --loop;
			}
			break;
		case ']':
			if (buffer[buffer_ptr] == 0) break;
			for (--code_ptr; loop > 0 || code[code_ptr] != '['; --code_ptr) {
				if (code[code_ptr] == ']') ++loop;
				if (code[code_ptr] == '[') --loop;
			}
			--code_ptr;
			break;
		}
	}
	return 0;
}
```

#ソースコード(その他 C++)

```cpp:Source.cpp
#include <cstdio>
#include <cstdint>
#include <string>

int main(int argc, char *argv[])
{
	//ファイルが指定されていない時のエラー処理
	if (argc != 2) {
		std::printf("開くファイルを指定してください。\n");
		return -1;
	}
	//ファイルが開けない時のエラー処理
	std::FILE *fp = nullptr;
	if ((fp = std::fopen(argv[1], "r")) == nullptr) {
		std::printf("ファイルを開くことが出来ません。\n");
		return -1;
	}

	//コードを読み取って格納
	char read_char;
	std::string code{};
	while ((read_char = std::fgetc(fp)) != EOF) {
		code.push_back(read_char);
	}
	std::fclose(fp);

	//コードを処理
	constexpr std::size_t buffer_size = 30000;
	char buffer[buffer_size]{};
	std::size_t buffer_ptr = 0;
	std::int_fast32_t loop = 0;

	const std::size_t code_len = code.size();
	for (std::size_t code_ptr = 0; code_ptr < code_len; ++code_ptr) {

		switch (code[code_ptr]) {
		case '>':++buffer_ptr; break;
		case '<':--buffer_ptr; break;
		case '+':++buffer[buffer_ptr]; break;
		case '-':--buffer[buffer_ptr]; break;
		case '.':std::putchar(buffer[buffer_ptr]); break;
		case ',':buffer[buffer_ptr] = std::getchar(); break;
		case '[':
			if (buffer[buffer_ptr] != 0) break;
			for (++code_ptr; loop > 0 || code[code_ptr] != ']'; ++code_ptr) {
				if (code[code_ptr] == '[') ++loop;
				if (code[code_ptr] == ']') --loop;
			}
			break;
		case ']':
			if (buffer[buffer_ptr] == 0) break;
			for (--code_ptr; loop > 0 || code[code_ptr] != '['; --code_ptr) {
				if (code[code_ptr] == ']') ++loop;
				if (code[code_ptr] == '[') --loop;
			}
			--code_ptr;
			break;
		}
	}
	return 0;
}
```

#出力
```:h.bf
+++++++++[>++++++++>+++++++++++>+++++<<<-]>.>++.+++++++..+++.>-.
------------.<++++++++.--------.+++.------.--------.>+.
```

```:出力
$ brainc.exe h.bf
Hello, World!
```

#他言語での実装

コンパイラ・インタプリタ、ともに載せています。
[Rust >> brainf*ck](https://qiita.com/kmtoki/items/341338029b3d4a6f0fab)
[Javascript >> シラミ騒動で Brainf**k](https://qiita.com/yoshinarl/items/6d16309a45ccef8abbd3)
[D言語 >> D言語でBrainf](https://qiita.com/CreateLGC/items/2df46063a297b3236d7e)
[C# >> Brainf*ck .NET](https://qiita.com/v-nakamuray/items/56089b31766ce2406542)
[Ruby >> Brainf*ck | RubyでBrainf*ckのコードを生成する](https://qiita.com/tbpgr/items/bb80d1758c6218181f92)
[Ruby >> brainf*ckを書いてみた](https://qiita.com/mdaisuke/items/49a12b9051fcb327e8dc)
[JavaScript >> Node.jsでPEG.jsでBrainf*ck](https://qiita.com/uehaj/items/68fa097e03d0572aefe4)
[C >> c言語でBrainf*ckインタプリタ](https://qiita.com/kasari/items/043764c4b3ba87a547e3)
[D >> D言語でBrainf*ckコンパイル時コンパイラを作ろう](https://qiita.com/simikaniku/items/4913063b937ba0d4928c)
[JavaScript >> JavaScriptでBrainF*ckインタプリタを実装する](https://qiita.com/gatayama/items/cf8e68a1e27b8d366712)
[解説 >> 今すぐBrainf*ckを始めるべき10の理由](https://qiita.com/Ark/items/d87e711d2a988d02de2e)

##ソースコードのライセンス

These codes are licensed under CC0.
[![CC0](https://mirrors.creativecommons.org/presskit/buttons/88x31/svg/cc-zero.svg "CC0")](http://creativecommons.org/publicdomain/zero/1.0/deed.ja)

ソースコードは自由に使用してください。