あまりに何年も前、私は
printf("%3.3s",
("NULSOHSTXETXEOTENQACKBELBS HT LF VT FF CR SO SI "
"DLEDC1DC2DC3DC4NAKSYNETBCANEM SUBESCFS GS RS US ")[3*ch]);
のようなものではなく、その特に優れているために書かれているだろう。また、8ビットのマイクロは乗算されないので、シフトと加算の両方を必要とし、スペアレジスタも必要になるため、3倍の乗算は面倒です。
C言語のような結果は、NULバイトを含むコントロールごとに4バイトのテーブルを使用することです。これにより、各エントリを文字列定数と呼ぶことができますが、32個のポインタの余分な記憶域を節約できます。
const char *charname(int ch) {
if (ch >= 0 && ch <= 0x20)
return ("NUL\0" "SOH\0" "STX\0" "ETX\0" /* 00..03 */
"EOT\0" "ENQ\0" "ACK\0" "BEL\0" /* 04..07 */
"BS\0\0" "HT\0\0" "LF\0\0" "VT\0\0" /* 08..0B */
"FF\0\0" "CR\0\0" "SO\0\0" "SI\0\0" /* 0C..0F */
"DLE\0" "DC1\0" "DC2\0" "DC3\0" /* 10..13 */
"DC4\0" "NAK\0" "SYN\0" "ETB\0" /* 14..17 */
"CAN\0" "EM\0\0" "SUB\0" "ESC\0" /* 18..1B */
"FS\0\0" "GS\0\0" "RS\0\0" "US\0\0" /* 1C..1F */
"SP\0\0") + (ch<<2); /* 20 */
if (ch == 0x7f)
return "DEL";
if (ch == EOF)
return "EOF";
return NULL;
}
メインテーブルを整理してその組織が明確になるようにしました。この関数は、自分自身の名前を持つ文字、または7ビットASCIIでない文字の場合はNULLを返します。それ以外の場合は、その制御文字の従来の省略形を含むNUL終端のASCII文字列へのポインタ、またはファイルの最後にC標準のIOルーチンによって返された非文字の "EOF" EOF
を返します。
各文字名のスロットを正確に4バイトにする努力に注意してください。これは、スクリプト言語や別のプログラムでこのテーブルを構築することは良い考えです。その場合、単純な答えは、EOF
の余分なスロットを持つすべての7ビットASCII(または8ビットの拡張コードページ)文字を含む129エントリテーブル(または257エントリ)を構築することです。
EOF
の余分なスペースを処理するサンプルについては、<ctype.h>
で宣言されている関数のソースを参照してください。
私はCマスターではありませんが、スイッチの最初の部分を文字列の配列に置き換えることができます。 – svens
文字列は配列であり、ポインタではありません。したがって、以下のsvensのアドバイスは2d配列を必要とします。これは特に、すべての文字列が同じ(またはほぼ同じ)長さを持つこのような場合に最適な実装です。 –