解决open()不能打开带中文的文件路径
首先,用一个简单的例子来重现一下我所遇到的问题:
(1)在VS2008的“Property Pages”属性页中,选择“Configuration Properties”-->“General”,可以看到当前使用的字符集是“Multi-Byte Character Set”,也就是说程序中使用的是多字节字符集。
(2)接下来看看ifstream打开txt文件的简单代码:
- #include "stdafx.h"
- #include <fstream>
- #include <iostream>
- using namespace std;
- int _tmain(int argc, _TCHAR* argv[])
- {
- ifstream infile("d://测试.txt");
- if(infile.is_open())
- {
- cout<<"Open Success!";
- }
- else
- {
- cout<<"Open Fail!";
- }
- return 0;
- }
(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()不能打开带中文的文件路径相关推荐
- Python 处理带中文 Excel 文件
Python 处理带中文 Excel 文件 Python-Excel常规操作 安装库 写入 Excel 读取 Excel 测试文件 处理中文 Ref 所遇到问题 Python-Excel常规操作 注意 ...
- 利用Navicat Premium将SQL Server数据库转为My SQL数据库(解决Mac无法打开SQL Server 脚本文件的方法)
利用Navicat Premium将SQL Server数据库转为My SQL数据库(解决Mac无法打开SQL Server 脚本文件的方法) 安装好Navicat Premium,SQL Serve ...
- 错误:无法打开web项目”****“,文件路径“****”与url“**”不符。这两者要映射到相同的服务器位置。...
问题出现的环境: 现在解决方案中有3个项目(2个类库,1个web),因为原来搭建项目的服务器要做别的用,所以要做个项目"迁移". 在现在的服务器上安装完开发环境,拷贝过来项目文件, ...
- 剖析ifstream打开含中文路径名文件失败的原因
http://blog.csdn.net/yukin_xue/article/details/7543423 最近写程序的时候遇到了使用ifstream打开含中文路径文件时失败的问题,在网上翻了一下, ...
- python打开文件中文名_windows下Python打开包含中文路径名文件
windows使用gbx(gb2312,gbk,gb18030我也不知道是哪个)对文件名及文件路径进行编码保存.打开文件的函数中使用诸如open(filename.encode('gbk'))可以很好 ...
- 解决Excel 2010打开两个以上文件时,总只显示一个窗口
用Excel 2010打开两个以上文件时,总只显示一个窗口. 解决方法,打开注册表编辑器,(点运行,输入regedit)定位到 HKEY_CLASSES_ROOT\Excel.Sheet.12\she ...
- 解决fstream不能打开带有中文路径文件的问题
方法1:使用_TEXT()宏定义将字符串常量指定为TCHAR*类型 方法2:使用STL中的locale类的静态方法指定全局locale,静态函数locale::global(newloc)可设置new ...
- 解决delphi直接打开bpg工程组文件后提示PROJECTS macro in project group file missing or incorrect丢失错误
前言: 所谓.bpg文件就是指在delphi中能一次性打开多个.dpr的工程组文件(Borland Project Group File). 出错环境: Win7-64+Delphi7.0 出错界面: ...
- 使用TkMybatis逆向生成带中文注释文件,并使用其常用的方法
首先说明,博主用的是springboot,如使用原生态的mybatis的一些配置文件请自行百度 贴上pom文件 <?xml version="1.0" encoding=&q ...
最新文章
- Slog64_项目上线之ArthurSlog个人网站上线3
- 构造图 Codeforces Round #236 (Div. 2) C. Searching for Graph
- 模块--random
- Windbg教程-调试非托管程序的基本命令上
- Crawler - 如何爬取列表后进行文章的爬取
- PHP Smarty无法解析模板文件
- 如何让apache支持php,Apache怎么才能支持PHP程序?
- axios_的其他方式发送请求_使用axios.request .get .delete .post .put 等方法发送请求---axios工作笔记005
- 思科全球云指数:2010-2015预测报告
- Qt 中 链接Ws2_32.lib
- Qt天气助手小程序(QCutomPlot绘图)
- 【WPS表格】从身份证号码提取各种信息,如出生日期、年龄、性别、户籍所在地
- Excel小技巧,隔行变色,多行变色
- 目前我国每小时就有1名电动自行车骑行者死于交通事故
- C++:什么是RAII? | 智能指针的初步讲解 | 智能指针是为了避免什么问题?| 被遗弃的auto_ptr
- DS1302时钟芯片(SPI协议)
- 数模2019暑期培训Day1
- Bootstrap4文件上传控件美化
- 名额已排到10月 | Apache DolphinScheduler Meetup分享嘉宾继续火热招募中~
- 圆形上下挤压 matlab,基于Matlab的GUI设计双螺杆挤压机系统仿真软件
热门文章
- cad调了比例因子没反应_天正CAD标注比例大小调整方法
- MVC5+HTML5 背景轮播图
- 七夕情人节生日表白爱心
- 远程桌⾯连接电脑后键盘失灵解决方案
- php 高德地图创建标注,使用高德地图API生成带标的专属地图
- 小米盒子 远程访问 计算机,小米盒子、电视远程安装电视狗视频图文教程
- 瑞禧研究Boc-Val-Dil-Dap及其衍生物(OH/Phe-OMe/Doe/Dap-Nrp/)——抗体药物偶联物
- 终于搞定Paypal了
- 你应该知道的10种软件工具
- php让手机全屏,手机网站按比例显示铺满手机全屏/网站两边不留白