我假设您在将源代码中的字符串文字和字符文字转换为机器代码时要检查您的编译器是否使用 ascii 编码。
std中有is_ascii这样的函数吗?
我不知道。
我可以用 if (65 == 'A' && ...) 之类的方法自己实现 is_ascii,它会枚举整个 ASCII 字符集
那就这样做吧。检查可以是c-char的字符,所以都来自basic source character set:
a b c d e f g h i j k l m n o p q r s t u v w x y z
A B C D E F G H I J K L M N O P Q R S T U V W X Y Z
0 1 2 3 4 5 6 7 8 9
_ { } [ ] # ( ) < > % : ; . ? * + - / ^ & | ~ ! = , \ " '
和转义序列:
\a \b \f \n \r \t \v
没有办法检查“整个”ASCII 字符集,因为编译器不会将程序转录为整个 ASCII 字符集。它只将基本字符集字符和转义序列映射到它的机器表示,而不是整个字符集(可能有编译器扩展)。
但这很烦人。
但这是唯一的方法。要验证您的实现使用了一些字符集,您必须检查它使用的所有字符。所以检查他们。无论如何都会是consteval。
如何检查不可打印的字符,如 SOH(标题开头)等。
不要。 SOH 字符不能在字符文字中,您不必检查它们,因为不可能用 C 语言表达它。没有\SOH 转义序列,0x01 字节不在基本字符集内。您的编译器从不将字符序列转换为 SOH 字符。一个有效的程序只能由基本源字符集中的字符组成。 SOH 字符的解释取决于将要接收它的东西,如果我写'\001',它将是等于1 的字节,与编码无关。 p>
嗯,让我们写吧!以下程序:
#include <type_traits>
#include <algorithm>
constexpr bool compiler_uses_ascii() {
return
'\a'==0x07 && '\b'==0x08 && '\t'==0x09 && '\n'==0x0a && '\v'==0x0b && '\f'==0x0c &&
'\r'==0x0d && '!'==0x21 && '#'==0x23 && '%'==0x25 && '&'==0x26 && '\''==0x27 &&
'('==0x28 && ')'==0x29 && '*'==0x2a && '+'==0x2b && ','==0x2c && '-'==0x2d &&
'.'==0x2e && '/'==0x2f && '0'==0x30 && '1'==0x31 && '2'==0x32 && '3'==0x33 &&
'4'==0x34 && '5'==0x35 && '6'==0x36 && '7'==0x37 && '8'==0x38 && '9'==0x39 &&
':'==0x3a && ';'==0x3b && '<'==0x3c && '='==0x3d && '>'==0x3e && '?'==0x3f &&
'A'==0x41 && 'B'==0x42 && 'C'==0x43 && 'D'==0x44 && 'E'==0x45 && 'F'==0x46 &&
'G'==0x47 && 'H'==0x48 && 'I'==0x49 && 'J'==0x4a && 'K'==0x4b && 'L'==0x4c &&
'M'==0x4d && 'N'==0x4e && 'O'==0x4f && 'P'==0x50 && 'Q'==0x51 && 'R'==0x52 &&
'S'==0x53 && 'T'==0x54 && 'U'==0x55 && 'V'==0x56 && 'W'==0x57 && 'X'==0x58 &&
'Y'==0x59 && 'Z'==0x5a && '['==0x5b && '\\'==0x5c && ']'==0x5d && '^'==0x5e &&
'_'==0x5f && 'a'==0x61 && 'b'==0x62 && 'c'==0x63 && 'd'==0x64 && 'e'==0x65 &&
'f'==0x66 && 'g'==0x67 && 'h'==0x68 && 'i'==0x69 && 'j'==0x6a && 'k'==0x6b &&
'l'==0x6c && 'm'==0x6d && 'n'==0x6e && 'o'==0x6f && 'p'==0x70 && 'q'==0x71 &&
'r'==0x72 && 's'==0x73 && 't'==0x74 && 'u'==0x75 && 'v'==0x76 && 'w'==0x77 &&
'x'==0x78 && 'y'==0x79 && 'z'==0x7a && '{'==0x7b && '|'==0x7c && '}'==0x7d &&
'~'==0x7e;
}
constexpr int char_index(char c)
{
if constexpr (compiler_uses_ascii()) {
return c - 'A';
} else {
// Is that right? Maybe it is.
const char a[] = "ABCDEFGHIJKLMNOPRSTUVXYZ";
return std::find(a, a + sizeof(a), c) - a;
#if 0
return
c == 'A' ? 0 : c == 'B' ? 1 : c == 'C' ? 2 : c == 'D' ? 3 :
c == 'E' ? 4 : c == 'F' ? 5 : c == 'G' ? 6 : c == 'H' ? 7 :
c == 'I' ? 8 : c == 'J' ? 9 : c == 'K' ? 10 : c == 'L' ? 11 :
c == 'M' ? 12 : c == 'N' ? 13 : c == 'O' ? 14 : c == 'P' ? 15 :
c == 'Q' ? 16 : c == 'R' ? 17 : c == 'S' ? 18 : c == 'T' ? 19 :
c == 'U' ? 20 : c == 'V' ? 21 : c == 'W' ? 22 : c == 'X' ? 23 :
c == 'Y' ? 24 : c == 'Z' ? 25 : -1;
#endif
}
}
#include <iostream>
int main() {
std::cout << compiler_uses_ascii() << " " << char_index('B') << "\n";
}
执行时输出:
$ g++ 1.cpp -std=c++20 && ./a.out
1 1
$ g++ 1.cpp -fexec-charset=IBM-1047 -std=c++20 && ./a.out
0@1%