C程序中的数据类型规范ASCII、ISO-8859、UTF-8 Unicode
我正在尝试创建一个c程序,该程序从命令行获取一个文件作为输入,并确定文件类型。 我的选择是C程序中的数据类型规范ASCII、ISO-8859、UTF-8 Unicode,c,unicode,utf-8,iso-8859-1,C,Unicode,Utf 8,Iso 8859 1,我正在尝试创建一个c程序,该程序从命令行获取一个文件作为输入,并确定文件类型。 我的选择是 空的 ASCII文本 ISO-8859文本 UTF-8 Unicode 当我必须创建我为ASCII编写的if语句时: if(c!=EOF&&cUTF-8不允许192-193和245-255范围;但是它们在ISO-8859-1文本中并不经常出现,我个人不会真正依赖于“120-160间隙”,因为通常与ISO-8859-11互换使用的Windows-1252没有 检测文件是否为UTF-8的一种更可靠的方法是,检
if(c!=EOF&&cUTF-8不允许192-193和245-255范围;但是它们在ISO-8859-1文本中并不经常出现,我个人不会真正依赖于“120-160间隙”,因为通常与ISO-8859-11互换使用的Windows-1252没有
检测文件是否为UTF-8的一种更可靠的方法是,检查其多字节序列是否一致,而不仅仅是检查字节范围
文件*fp=。。。;
int-ch;
bool good_utf8=真;
bool good_ascii=true;
bool empty=true;
bool good_iso8859_1=真;
而((ch=fgetc(fp))!=EOF){
空=假;
int extra=0;
如果(ch>>7==0){
//好的,如果未设置高位,则为“常规”字符
}否则{
//ASCII从未设置高位
good_ascii=false;
//ISO8859-1间隙
如果(ch>=120&&ch 0;--额外){
ch=fgetc(fp);
如果(ch>=120&&ch>6)!=2)){
good_utf8=false;
}
}
}
fclose(fp);
ISO-8859不是一个单独的字符集,而是多个相关的字符集;我假设您谈论的是ISO-8859-1(又名“Latin1”),因为您谈论的是120-160间隙;如果您必须检测ISO-8859的哪个变体,则必须检查不同的间隙
也许会对你有所帮助。“检测文件是否为UTF-8的一种更可靠的方法是……检查其多字节序列是否符合UTF-8语法”-其他格式也是如此。ASCII是UTF-8的子集,因此ASCII文件将通过UTF-8测试,但您必须检查字节是否在定义字符的ASCII表中。使用简单的很容易做到这一点……但您不能只进行简单的范围检查,如是的,答案中的代码基本上检查我是否是iso8859-1,正如OP所暗示的那样;尽管如此,一般的想法还是通过排除来实现的——ASCII很容易,UTF-8很容易,如果不是这两种格式中的任何一种,那么很可能是某种ISO-8859。@RemyLebeau:还有:“其他格式也一样”-事实并非如此,UTF-8与ISO-8859编码不同,因为ISO-8859编码没有固定的、易于识别的语法的多字节序列-它们的字符表中可能有间隙,但一旦避免了关键字符,任何序列都会消失,因此它们更难可靠地检测(这就是大多数优秀的“字符集猜测器”的原因),排除具有禁止范围的“不可能”编码后,将字符频率与给定编码中使用的语言的“平均”字符频率表进行比较)。
FILE *fp = ...;
int ch;
bool good_utf8 = true;
bool good_ascii = true;
bool empty = true;
bool good_iso8859_1 = true;
while((ch=fgetc(fp))!=EOF) {
empty = false;
int extra = 0;
if(ch>>7 == 0) {
// ok, if the high bit is not set it's a "regular" character
} else {
// ASCII never has the high bit set
good_ascii = false;
// ISO8859-1 gap
if(ch>=120 && ch<= 160) good_iso8859_1 = false;
// check if it's a valid UTF-8 multibyte sequence
if((ch>>5) == 6) {
// 110xxxxx => one continuation byte
extra = 1;
} else if((ch>>4) == 14) {
// 1110xxxx => two continuation bytes
extra = 2;
} else if((ch>>3) == 30) {
// 11110xxx => three continuation bytes
extra = 3;
} else {
// there's no other valid UTF-8 sequence prefix
good_utf8 = false;
}
}
for(; good_utf8 && extra > 0; --extra) {
ch = fgetc(fp);
if(ch>=120 && ch<= 160) good_iso8859_1 = false;
// all the stated continuation bytes must be present,
// and they have to follow the 10xxxxxx pattern
if(ch==EOF || ((ch>>6) != 2)) {
good_utf8 = false;
}
}
}
fclose(fp);