首先,用一个简单的例子来重现一下我所遇到的问题:

(1)在VS2008的“Property  Pages”属性页中,选择“Configuration Properties”-->“General”,可以看到当前使用的字符集是“Multi-Byte Character Set”,也就是说程序中使用的是多字节字符集。

(2)接下来看看ifstream打开txt文件的简单代码:

view plain
  1. #include "stdafx.h"
  2. #include <fstream>
  3. #include <iostream>
  4. using namespace std;
  5. int _tmain(int argc, _TCHAR* argv[])
  6. {
  7. ifstream infile("d://测试.txt");
  8. if(infile.is_open())
  9. {
  10. cout<<"Open Success!";
  11. }
  12. else
  13. {
  14. cout<<"Open Fail!";
  15. }
  16. return 0;
  17. }

(3)运行结果:输出“Open Fail”  (打开文件失败!)

从设置选项中可以看到,工程中使用的字符集可设置为“Multi-Byte Character Set”或“Unicode Character Set”,其中“Multi-Byte Character Set”表示使用ANSI编码方式,“Unicode Character Set”表示使用UNICODE编码方式。

那么这两种编码方式有什么样的区别呢?

(1)传统的计算机使用ANSI编码,在ANSI编码模式下,英文字符都用1个字节表示,而某些其它国家的文字(如汉字、日文),无法用单个字节来表示,ANSI便采用多个字节来表示这些字符(汉字是2个字节)。

(2)UNICODE包含UTF-8、UTF-16、UTF-32等多种编码方案(目前windows一般使用UTF-16)。拿UTF-16来说,规定所有字符都使用2个字节表示(不论英文字母还是汉字),对于超出2个字节范围的字符采用代理(采用4个字节表示)。

UNICODE相比ANSI有很多方面的优势(优势体现在哪?),微软非常提倡使用UNICODE编码方式,在MS较新版本的系统中都是采用UNICODE编码的。因此,即便我们在自己写的程序中使用了ANSI编码,系统会将其转换为UNICODE再对其进行处理。

接下来我们说一下ifstream。在调用ifstream的open方法时,系统内部调用mbstowcs_s进行文件名转换(mbstowcs_s函数的作用是把多字节字符转化为宽字符),需要注意的是,该函数的调用结果依赖于程序的本地化设置(什么是本地化设置?)。而本地化设置可以通过setlocale函数来设置,譬如:setlocale(LC_ALL, "chinese")表示将程序本身的语言设置为中文,而程序启动时默认设置为LC_ALL="C"。在使用mbstowcs_s进行字符串转换时,只有当LC_ALL="chinese"时,含中文的字符串才能正确的转换成其对应的宽字节字符,否则(在LC_ALL="C"时),汉字会被看成2个单字节的字符,然后再转换成宽字节的字符,这样转换的结果显然是错误的!这就是ifstream打开含中文路径的文件失败的原因,因为"d://测试.txt"转换后得到错误的路径,因此文件打不开!

解决方法如下:

1: /********************************************************************
2: created: 2008/05/10
3: created: 10:5:2008 23:56
4: filename: k:/sj/fstreamTest/fstreamTest/main.cpp
5: file path: k:/sj/fstreamTest/fstreamTest
6: file base: main
7: file ext: cpp
8: author: Gohan
9: *********************************************************************/
10: #include <tchar.h>
11: #include <fstream>
12: #include <iostream>
13: using namespace std;
14: int main()
15: {
16: /************************************************************************/
17: /* 方法1,使用_TEXT()宏定义将字符串常量指定为TCHAR*类型 */
18: /* 如果是我,首选此类型 */
19: /************************************************************************/
20: fstream file;
21: file.open(_TEXT("c://测试//测试文本.txt"));
22: cout<<file.rdbuf();
23: file.close();
24: 
25: /************************************************************************/
26: /* 方法2,使用STL中的locale类的静态方法指定全局locale */
27: /* 使用该方法以后,cout可能不能正常输出中文,十分蹊跷 */
28: /* 我发现了勉强解决的方法:不要在还原区域设定前用cout或wcout 输出中文 */
29: /* 否则后果就是还原区域设定后无法使用cout wcout输出中文 */
30: /************************************************************************/
31: locale::global(locale(""));//将全局区域设为操作系统默认区域
32: file.open("c://测试//测试文本2.txt");//可以顺利打开文件了
33: locale::global(locale("C"));//还原全局区域设定
34: cout<<file.rdbuf();
35: file.close();
36: 
37: /************************************************************************/
38: /* 方法3,使用C函数setlocale,不能用cout输出中文的问题解决方法同上 */
39: /************************************************************************/
40: setlocale(LC_ALL,"Chinese-simplified");//设置中文环境
41: file.open("c://测试//测试文本3.txt");//可以顺利打开文件了
42: setlocale(LC_ALL,"C");//还原
43: cout<<file.rdbuf();
44: file.close();
45: }

参见博客:http://www.cppblog.com/gohan/archive/2008/05/11/49488.html

由于windows提倡使用UNICODE编码,因此,我们在使用VS编写程序的时候,最好也都使用UNICODE字符集。这样有利于避免字符集转换带来的问题,同时,也有利于提高效率(前面提到,windows内部会把ANSI编码转换为UNICODE再处理,这些转换当然也带来了额外的时间消耗)。

在示例的程序中,可以将工程字符集设置为UNICODE,然后将字符串前面加上_T(这样,在字符集已经设置为UNICODE的情况下,该字符串会自动采用宽字符表示),例如:ifstream infile(_T("d://测试.txt")),便不会有打开文件不成功的问题了。

注:红色字体部分,作为扩展问题,自己查阅相关资料。

解决open()不能打开带中文的文件路径相关推荐

  1. Python 处理带中文 Excel 文件

    Python 处理带中文 Excel 文件 Python-Excel常规操作 安装库 写入 Excel 读取 Excel 测试文件 处理中文 Ref 所遇到问题 Python-Excel常规操作 注意 ...

  2. 利用Navicat Premium将SQL Server数据库转为My SQL数据库(解决Mac无法打开SQL Server 脚本文件的方法)

    利用Navicat Premium将SQL Server数据库转为My SQL数据库(解决Mac无法打开SQL Server 脚本文件的方法) 安装好Navicat Premium,SQL Serve ...

  3. 错误:无法打开web项目”****“,文件路径“****”与url“**”不符。这两者要映射到相同的服务器位置。...

    问题出现的环境: 现在解决方案中有3个项目(2个类库,1个web),因为原来搭建项目的服务器要做别的用,所以要做个项目"迁移". 在现在的服务器上安装完开发环境,拷贝过来项目文件, ...

  4. 剖析ifstream打开含中文路径名文件失败的原因

    http://blog.csdn.net/yukin_xue/article/details/7543423 最近写程序的时候遇到了使用ifstream打开含中文路径文件时失败的问题,在网上翻了一下, ...

  5. python打开文件中文名_windows下Python打开包含中文路径名文件

    windows使用gbx(gb2312,gbk,gb18030我也不知道是哪个)对文件名及文件路径进行编码保存.打开文件的函数中使用诸如open(filename.encode('gbk'))可以很好 ...

  6. 解决Excel 2010打开两个以上文件时,总只显示一个窗口

    用Excel 2010打开两个以上文件时,总只显示一个窗口. 解决方法,打开注册表编辑器,(点运行,输入regedit)定位到 HKEY_CLASSES_ROOT\Excel.Sheet.12\she ...

  7. 解决fstream不能打开带有中文路径文件的问题

    方法1:使用_TEXT()宏定义将字符串常量指定为TCHAR*类型 方法2:使用STL中的locale类的静态方法指定全局locale,静态函数locale::global(newloc)可设置new ...

  8. 解决delphi直接打开bpg工程组文件后提示PROJECTS macro in project group file missing or incorrect丢失错误

    前言: 所谓.bpg文件就是指在delphi中能一次性打开多个.dpr的工程组文件(Borland Project Group File). 出错环境: Win7-64+Delphi7.0 出错界面: ...

  9. 使用TkMybatis逆向生成带中文注释文件,并使用其常用的方法

    首先说明,博主用的是springboot,如使用原生态的mybatis的一些配置文件请自行百度 贴上pom文件 <?xml version="1.0" encoding=&q ...

最新文章

  1. Slog64_项目上线之ArthurSlog个人网站上线3
  2. 构造图 Codeforces Round #236 (Div. 2) C. Searching for Graph
  3. 模块--random
  4. Windbg教程-调试非托管程序的基本命令上
  5. Crawler - 如何爬取列表后进行文章的爬取
  6. PHP Smarty无法解析模板文件
  7. 如何让apache支持php,Apache怎么才能支持PHP程序?
  8. axios_的其他方式发送请求_使用axios.request .get .delete .post .put 等方法发送请求---axios工作笔记005
  9. 思科全球云指数:2010-2015预测报告
  10. Qt 中 链接Ws2_32.lib
  11. Qt天气助手小程序(QCutomPlot绘图)
  12. 【WPS表格】从身份证号码提取各种信息,如出生日期、年龄、性别、户籍所在地
  13. Excel小技巧,隔行变色,多行变色
  14. 目前我国每小时就有1名电动自行车骑行者死于交通事故
  15. C++:什么是RAII? | 智能指针的初步讲解 | 智能指针是为了避免什么问题?| 被遗弃的auto_ptr
  16. DS1302时钟芯片(SPI协议)
  17. 数模2019暑期培训Day1
  18. Bootstrap4文件上传控件美化
  19. 名额已排到10月 | Apache DolphinScheduler Meetup分享嘉宾继续火热招募中~
  20. 圆形上下挤压 matlab,基于Matlab的GUI设计双螺杆挤压机系统仿真软件

热门文章

  1. cad调了比例因子没反应_天正CAD标注比例大小调整方法
  2. MVC5+HTML5 背景轮播图
  3. 七夕情人节生日表白爱心
  4. 远程桌⾯连接电脑后键盘失灵解决方案
  5. php 高德地图创建标注,使用高德地图API生成带标的专属地图
  6. 小米盒子 远程访问 计算机,小米盒子、电视远程安装电视狗视频图文教程
  7. 瑞禧研究Boc-Val-Dil-Dap及其衍生物(OH/Phe-OMe/Doe/Dap-Nrp/)——抗体药物偶联物
  8. 终于搞定Paypal了
  9. 你应该知道的10种软件工具
  10. php让手机全屏,手机网站按比例显示铺满手机全屏/网站两边不留白