是否保证 mbcs 编码中的尾随字节在特定范围内?

Is it guaranteed that trailing bytes in mbcs encodings are in specific range?

我需要读取包含任意 MBCS 编码字符串的文本文件。文件格式(简化)如下:

CODEPAGE "STRING"
CODEPAGE STRING
...

其中 CODEPAGE 可以是任何 MBCS 代码页:UTF-8、cp1251(西里尔字母)、cp932(日语)等

我无法一次调用 MultiByteToWideChar 来解码整个文件。我需要在引号之间或直到 space 或回车 return 之间提取字符串,然后在提取的字符串上调用 MultiByteToWideChar。

但是在MBCS(多字节编码方案)中,一个字符可以用多个字节表示。如果我想在多字节编码文件中查找拉丁语 'A',我不能只搜索代码 65,因为 65 可能是某些编码序列中的尾随字节。

所以我不确定是否允许我在 MBCS 字符串中搜索 '"' 或 space 或 CR。我浏览了几个代码页(例如中文 936 代码页:https://ssl.icu-project.org/icu-bin/convexp?conv=windows-936-2000&s=ALL ) 并且据我所知,所有尾随字节都从 0x40 开始,因此扫描文件中的标点符号是安全的。但是对于任何代码页是否有一些保证?

分析哪些八位位组可以出现在编码的八位位组序列中,丢弃领先的。结果是 0x40..0x7E, 0x80..0xFE.

#!/usr/bin/env perl
use Encode qw(encode);
my @encodings = qw(
    cp1006 cp1026 cp1047 cp1250 cp1251 cp1252 cp1253 cp1254 cp1255 cp1256
    cp1257 cp1258 cp37 cp424 cp437 cp500 cp737 cp775 cp850 cp852 cp855 cp856
    cp857 cp858 cp860 cp861 cp862 cp863 cp864 cp865 cp866 cp869 cp874 cp875
    cp932 cp936 cp949 cp950
);
my %continuation_octets;
for my $e (@encodings) {
    for my $c (0..0x10_ffff) {
        my $encoded = encode $e, chr($c), sub { -1 };
        if ($encoded ne -1 && length($encoded) > 1) {
            my @octets = split //, $encoded;
            shift @octets;
            $continuation_octets{$_}++ for @octets;
        }
    }
}