`
jgsj
  • 浏览: 1004473 次
文章分类
社区版块
存档分类
最新评论

解决:VS 2005/2008 中 fstream 不能处理带有中文路径的问题

 
阅读更多

转自:http://blog.csdn.net/code_robot/archive/2010/06/23/5688867.aspx

有时候用ifstream或ofstream打开带有中文路径的文件会失败。

解决办法:
1、使用C语言的函数设置为中文运行环境
setlocale(LC_ALL,"Chinese-simplified");


2、使用STL函数设置为系统语言环境
std::locale::global(std::locale(""));

当然选2啦!

ofstream writefile;

string filename=("d:/我的文档/测试.txt");

locale loc = locale::global(locale("")); //要打开的文件路径含中文,设置全局locale为本地环境

writefile.open(filename.c_str(),ios::out); //打开文件

locale::global(loc);//恢复全局locale

用locale对象的name方法可以看到,通过locale("")构造出的locale对象的name为"Chinese_People's Republic of China.936",而原始的locale对象的name为"C",也就是缺省的ANSI_C公约。

注意:如果使用locale loc = locale::global(locale(""))设置全局locale后没有用 locale::global(loc)恢复的话,那么在程序后面的cout语句就不能输出中文了,虽然这时候操作中文文件没有问题,但是这也是很容易让人掉入陷阱的地方,应该值得注意。解决方法:

先将CString 转为char*

CString str=view->m_sFilePath;
//CString str = "";
//ofstream 中传的参数不能有汉字,必须转换,一下是其暂缓方法
str.AppendFormat("cluster%d%d.txt",aMatrix->X_part,aMatrix->Y_part);
char* sz = str.GetBuffer(str.GetLength());
locale loc = locale::global(locale(""));
ofstream ofile(sz);

转自:http://anwj336.blog.163.com/blog/static/89415209200991931213190/

----------------------------------------------------------------------------------------------------------------------------------------------------


VC 2005中的locale
连续碰到两次和locale相关的问题,一次是ifstream, 一次是boost::format, 做了些实验记录下来:

1. ifstream 的文件名参数其实可以接受char *, 也可以接受wchar_t * 作为参数,如果接受char * 的话,实际上内部也是转换成为wchar_t *,但转换的时候问题就来了,如果此文件名里面有汉字,vc2005就转换不对,这样就打不开文件了。在vc2005中,一开始程序的缺省locale是”C”, 也就是std::locale::classic()返回的,但这个locale下,汉字转换是不正确的,所以,要先用 std::locale::global(std::locale(”"))这样的语句将locale设到系统缺省的。实际上std::locale::global(std::locale(”.936″)) 也是一样的。936就是简体中文的codepage(代码页)。 此时用 locale.name() 打印出来的locale名称为: “Chinese_People’s Republic of China.936″

2. 但是一旦locale变为936了,cout 输出中文就又会有问题,碰到中文就会断掉,而且后面的东西再也显示不出来。这可以通过在ifstream打开文件之后,用std::locale::global(std::locale(”C”))再设回缺省locale来解决。

3. locale设为936的另一个问题是,boost::format 中 如果输出数字的话,1234会变成1, 234. 这个问题也可以用上面的方法来解决。另外一个方法是可以用format的第二个参数来做,例如std::locale::classic() 或者std::locale(”C”);

4. 网上说流输出时候也会将1234变为 1,234,但我直接实验cout << 1234 好像没有问题。看到说碰到这种情况,需要用a.imbue(std::locale(”C”))。

5. 如果ifstream直接用wchar_t *的文件名参数,就很简单了,由于不更改locale就可以打开文件,后面的cout输出汉字也没有问题,boost::format也没有问题。所以竭力推荐这种方法

---------------------------------------------------------------------------------------------------------------------------------------------

一. locale
一个流在初始化时将隐式地使用全局locale, 而初始时候的全局locale就是标准的"C"模式locale::classic()
在VC与中文版xp下, 也是这样。

二. 静态函数locale::global(newloc) 可设置newloc为全局locale,并且返回以前的全局locale,可将之保存起来
以后恢复, 随时要记得恢复这点很重要。
locale newloc(""); //在简体中文xp系统上等价于".936"
locale& oldloc = locale::global(newloc);
...
locale::global(oldloc);

纯API方式下用
setlocale(LC_ALL,"C");
setlocale(LC_ALL,".936"); 也可以用 setlocale(LC_ALL, "");

三. Bjarne Stroustrup提到用locale::global(x)的时候将同时设置全局locale,但我在VC中混用API
和stl的来设置locale时候有些微小的差别,所以今后要注意最好成对地设置,也就是用API去设置,以后恢复也用
API来做,相应地,用stl类locale去设置,也用同样的类去恢复回来。

转自:http://hi.baidu.com/eith/blog/item/4525a016635f9c5df3de3294.html

分享到:
评论

相关推荐

    AddLineNum.rar_C++读取文本_文本文件 读取_读取文本文件

    接下来,我们需要定义两个文件流对象,一个用于读取原始文本文件,另一个用于写入带有行号的新文本文件: ```cpp std::ifstream inputFile("原始文本文件.txt"); // 读取文件 std::ofstream outputFile("新文本文件...

    城市路径查找

    这两种算法都是用于解决带权重的无向图中最短路径的问题,但它们的策略和实现方式有所不同。 首先,克鲁斯卡尔算法是一种基于贪心思想的算法。它的核心理念是按照边的权重从小到大依次考虑,每次添加一条不会形成环...

    数据结构实验-图-求最短路径

    总的来说,这个实验旨在通过实际操作加深对图的存储结构和最短路径算法的理解,特别是迪杰特斯拉算法的应用,以及如何扩展其以解决更复杂的问题,如寻找图中最短的闭合回路。通过这样的实践,学生能够提升其在数据...

    数据结构实验报告利用Huffman编码对文件进行压缩解压 (2).pdf

    在实习过程中,学生遇到的主要问题包括程序运行效率低、文件块读写操作的困难,以及C++fstream库在处理中文文件名和空格路径上的局限性。通过优化文件读写方式,使用文件块缓存,解决了效率问题;通过调试找到了文件...

    数据结构实验报告利用Huffman编码对文件进行压缩解压.docx

    实验中遇到的问题之一是C++的fstream库在处理中文文件名和带空格的路径时存在困难,而C语言的FILE*接口则没有这个问题。此外,fstream的read函数返回值并不直接表示读取成功的项数,这导致了一些困扰。转换为使用C...

    类操作总结

    ### 类操作总结——文件流详解 #### 一、文件流的基本概念 文件是计算机系统中存储数据的一种形式,它可以是二进制数、字符或源代码等任何形式...通过对这些操作的理解和掌握,可以更灵活地在C++程序中处理文件数据。

    文本分割软件

    5. 用户界面(UI):如果TextsplitApp.exe是一个带有图形用户界面的应用,那么还可能涉及到MFC(Microsoft Foundation Classes)或WinAPI等技术,以便用户可以直观地输入参数,如输入文件路径、设定分割规则等。...

    Ini配置文件读写源码

    为了实现跨平台,我们需要处理不同操作系统下的路径和文件权限问题。在 Windows 上,文件路径通常使用反斜杠(\),而在 Linux 上则是正斜杠(/)。此外,Linux 对文件权限的管理更为严格,可能需要在打开文件时指定...

    校园导游系统 带有图形界面 源码下载

    10. **版本控制与调试**:在开发过程中,版本控制工具如Git用于协同开发和版本管理,Visual Studio的调试工具则帮助开发者定位和修复代码中的问题。 总的来说,"校园导游系统"的开发涵盖了MFC框架下的多个重要技术...

    利用堆实现带有文件操作的huffman编译码

    8. **实现细节**:在`利用堆实现带有文件操作的huffman编码.cpp`源文件中,应包含适当的头文件,定义数据结构(如节点类),实现堆操作(如插入、删除最小元素),以及哈夫曼编码和解码的算法。同时,文件操作的代码...

    迷宫求解的C++实现

    在本文中,我们将深入探讨如何使用C++编程语言实现一个迷宫求解算法。迷宫求解是一个经典的计算机科学问题...同时,这个程序可以作为基础,扩展到其他问题,如解决带有多个起点和终点的迷宫,或者包含特殊规则的迷宫。

    C++课件之流文件示例

    在C++中,标准输入输出流对象`cin`代表键盘输入(标准输入),`cout`代表显示器输出(标准输出),它们都带有缓冲功能。 流文件主要分为两种类型:文本文件和二进制文件。文本文件通常包含ASCII字符,每个字节存储...

    算法 Floyd 弗洛伊德算法

    Floyd在1962年提出,适用于有向图或无向图,能处理带有负权边的情况。在实际应用中,例如在交通网络、通信网络等领域,寻找最短路径是非常重要的问题。 **算法步骤:** 1. 初始化:创建一个n×n的距离矩阵D,其中D...

    cocos2dx解析CSV

    这个解析器可以根据需求进行扩展,比如支持引用符号(如双引号)内的逗号,或者处理带有注释的CSV文件。理解如何处理和解析CSV文件是游戏开发中的一个重要技能,因为它可以简化数据管理,使游戏逻辑更加清晰和可维护...

    as3带进度条上传实例

    本篇将详细介绍如何实现一个带有进度条的文件上传功能,包括连接服务器、发送文件以及更新进度条的具体步骤。 #### 一、项目概述 该示例代码主要实现了通过Socket连接服务器并上传文件的功能,同时在上传过程中...

    C++ 写日志函数

    这将向名为"app.log"的文件中写入一条带有"INFO"级别的日志信息。 7. **3.cpp 文件**:这个压缩包中的"3.cpp"文件可能包含了上述日志类的实现。通过阅读和理解代码,你可以看到具体如何使用C++的文件流、异常处理...

    VC 源码:操作TXT文本并独立读写存储文件.rar

    6. **异常处理**:为了防止文件操作过程中出现错误(如文件不存在或权限不足),通常会加入异常处理机制,如`try-catch`块,以便优雅地处理错误并提示用户。 7. **文件路径处理**:可能包含了对文件路径的合法性...

    pck.zip_PCK

    2. **文件操作**: 类需要能够读取和写入文件,这通常涉及到I/O流(如`fstream`在C++中)和文件路径处理。 3. **压缩算法**: "pck.zip_PCK" 带有 "zip" 字样,可能意味着这个工具支持ZIP压缩格式。因此,它可能使用...

    用C++实现有预览功能对话框控件

    本项目聚焦于使用C++编程语言实现一个带有预览功能的对话框控件,这是许多应用程序,尤其是文档编辑器或查看器软件中的常见特性。这种控件允许用户在不打开文件的情况下预览其内容,提高了用户体验。 首先,我们要...

Global site tag (gtag.js) - Google Analytics