关于window简体中文环境文件路径包含7种横杠的问题,及结论推广

直接说结论:
windows对多语言环境中的特殊字符并不完备,总有支持不到的地方,所以,建议禁止路径中出现非常规的六种横杠,仅允许英文横杠(-)(0x2D)。

此网页对编码总结比较到位:
https://blog.csdn.net/Liuqz2009/article/details/107861408

后面是个人的测试笔记

7种横杠:-‐‑‒–—― 第一个是英文ASCII码-(0x2D),其他为unicode 0x2010~0x2015
UTF16BE: FE FF 00 2D 20 10 20 11 20 12 20 13 20 14 20 15  unicode大尾
UTF16LE: FF FE 2D 00 10 20 11 20 12 20 13 20 14 20 15 20  unicode小尾
UTF8:             2D E2 80 90 E2 80 91 E2 80 92 E2 80 93 E2 80 94 E2 80 95 (3字节连续对应)
UTF8BOM: EF BB BF 2D E2 80 90 E2 80 91 E2 80 92 E2 80 93 E2 80 94 E2 80 95 (3字节连续对应)
ANSI:             2D A9 5C 3F 3F A8 43 A1 AA A8 44; -??–—― 第3(?0x2011)4(?0x2012)个横杠在当前CP936简体中文系统无对应。3F?号。

windows10简体中文系统创建txt默认是UTF8文件,对7-进行mkdir(bat脚本),只有一种执行成功。
如果在cmd中挨个执行,成功5次
mkdir -   成功:0x2D
mkdir ‐  
mkdir ?
mkdir ?
mkdir –  失败:子目录或文件 - 已经存在。 0x2013 (mkdir时失败,但鼠标右键可以创建)识别为了0x2D目录
mkdir —  失败:子目录或文件 - 已经存在。 0x2014 (mkdir时失败,但鼠标右键可以创建)识别为了0x2D目录
mkdir ―
cmd中显示都正常,unicode或utf8显示。
tree > 1.txt 导出的是ANSI文件,两个无法正常显示(说明资源浏览器不是ANSI)
├─-   0x2D
├─‐  0x2010
├─?   0x2011 显示失败,但可以拷贝到UTF16BE文件中
├─?   0x2012 显示失败,但可以拷贝到UTF16BE文件中
└─―  0x2015
最终正常的只有0x2D0x20100x2015
中文输入法(sogo)中文横杠对应的是0x2014 (mkdir时失败,但鼠标右键可以创建)
├─-   0x2D
├─‐  0x2010
├─?   0x2011 显示失败,但可以拷贝到UTF16BE文件中
├─?   0x2012 显示失败,但可以拷贝到UTF16BE文件中
├─–  0x2013
├─—  0x2014
└─―  0x2015
以下拷贝命令全部执行成功,但实际有两个目录为空,说明重复拷贝了两次,与mkdir失败一致(0x20130x2014)
copy /Y 1utf8bom.txt -   0x2D
copy /Y 1utf8bom.txt ‐
copy /Y 1utf8bom.txt ?
copy /Y 1utf8bom.txt ?
copy /Y 1utf8bom.txt –  重复拷贝到了0x2D目录
copy /Y 1utf8bom.txt —  重复拷贝到了0x2D目录,中文输入法(sogo)中文横杠对应的是0x2014
copy /Y 1utf8bom.txt ―  0x2015

结论:
1、QT5.5.1 QFile copy对中文横杠失败的根源在于windows10简体中文系统不支持目录含有0x20130x2014的目录拷贝。
2、ANSI对于显示0x20110x2012也不正常,所以至少要剔除0x2011~0x20144种横杠。
3、对于0x20100x2015,不清楚怎么通过输入法敲出来,也没有意义。(中文环境输出0x2D0x2014)
4、最终建议禁止目录或文件路径中出现0x2010~0x2015六种横杠。
5、横杠只允许出现英文0x2D(-)。禁止其他所有横杠。

相关检查代码

bool CheckPath(const std::string &str_path)
{
   //假定输入为windows local编码CP936 GBK版本
   if (str_path.length() == 0)
   {
         return false;
   }
   //即使部分windows函数能访问部分目录,但不是所有功能都正常,所以access判断没必要。
   //if (access(str_path.c_str(), 0) == 0)
   //{
   //   return true;//存在的都正常,可能是文件,也可能是目录
   //}
#pragma warning(push)
#pragma warning(disable:4566) //本句没有必要了,暂时保留。
#pragma execution_character_set("utf-8") //没有此句,strUtf8会被编译为ANSI
   const static std::string strUtf8 = "‐,?,?,–,—,―"; //warning C4566: 由通用字符名称“\u2011”表示的字符不能在当前代码页(936)中表示出来
#pragma warning(pop)
   //const static std::string strUtf8 = "‐,–,—,―"; //删除编译告警的两种横杠(0x2011)、(0x2012)
   //const static std::string strGB2312 = ToLocal(strUtf8);
   const static string_vec strUtf8_vec = split(strUtf8, ",");
   const std::string str_path_utf8 = ToUtf8(str_path);//ANSI 0xA1AA ==> UTF8 0xE28095 (UTF16BE 0x2015)这里说明iconv转换也不一定标准。
   for each (const std::string &strUtf8_temp in strUtf8_vec)
   {
         //const char *pCharTemp = strGB2312_temp.c_str();//测试,此处为ANSI编码A95C、A843、A1AA、A844。
         //const char *pCharTemp = strUtf8_temp.c_str();//测试,此处为utf8编码0xE28090 ~ 0xE28095
         if (str_path_utf8.find(strUtf8_temp) != std::string::npos)
         {              
              return false;
         }
   }
   return true;
}

以上有乱码是由于拷贝过程导致的,实际可以在unicode BE txt中编辑二进制数据获得7种横杠。
-‐‑‒–—―

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值