C++ writestring 为什么不能写进中文 CStdioFile向无法向文本中写入中文【二】
本地化设置需要具备三个条件:
a. 语言代码 (Language Code)
b. 国家代码 (Country Code)
c. 编码(Encoding)
本地名字可以用下面这些部分来构造:
语言代码_国家代码.编码 比如(zh_CN.UTF-8, en_US等) locale的别名表见 /usr/lib/X11/locale/locale.alias(以Debian GNU/Linux为例)
setlocale语言字符串参考 本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/ALENTAM/archive/2008/04/11/2281121.aspx 另外还有一种方法就是重新写CStdioFile的派生类CStdioFileEx(网上有)。 //好像C++中没有类能够读些Unicode格式的文本文件,所以我写了下面这个类。用法很简单,大家尝试几下就明白了。 #pragma once class CStdioFileEx: public CStdioFile
{
public:
CStdioFileEx();
CStdioFileEx( LPCTSTR lpszFileName, UINT nOpenFlags ); virtual BOOL Open( LPCTSTR lpszFileName, UINT nOpenFlags, CFileException* pError = NULL );
virtual BOOL ReadString(CString& rString);
BOOL ReadWideString(CStringW& rString);
BOOL ReadAnsiString(CStringA& rString);
virtual void WriteString(LPCTSTR lpsz);
void WriteWideString(LPCWSTR lpsz);
void WriteAnsiString(LPCSTR lpsz);
bool IsUnicodeFormat() {return m_bIsUnicodeText;}
unsigned long GetCharCount(); // Additional flag to allow Unicode text format writing
enum {modeWriteUnicode = 0x100000}; static bool IsFileUnicode(const CString& sFilePath); protected:
UINT PreprocessFlags(const CString& sFilePath, UINT& nOpenFlags); bool m_bIsUnicodeText;
}; //。cpp文件
#include "stdafx.h"
#include "StdioFileEx.h" //在UCS 编码中有一个叫做"ZERO WIDTH NO-BREAK SPACE"的字符,它的编码是FEFF。而FFFE在UCS中是不存在的字符,
//所以不应该出现在实际传输中。UCS规范建议我们在传输字节流前,先传输字符"ZERO WIDTH NO-BREAK SPACE"。这样
//如果接收者收到FEFF,就表明这个字节流是Big-Endian的;如果收到FFFE,就表明这个字节流是Little-Endian的。
//因此字符"ZERO WIDTH NO-BREAK SPACE"又被称作BOM。
//UTF-8不需要BOM来表明字节顺序,但可以用BOM来表明编码方式。字符"ZERO WIDTH NO-BREAK SPACE"的UTF-8编码是
//EF BB BF。所以如果接收者收到以EF BB BF开头的字节流,就知道这是UTF-8编码了。
//Windows就是使用BOM来标记文本文件的编码方式的。
//有些老的浏览器和文本编辑器不支持BOM。
#define UNICODE_BOM 0xFEFF//Unicode "byte order mark" which goes at start of file CStdioFileEx::CStdioFileEx(): CStdioFile()
{
m_bIsUnicodeText = false;
} CStdioFileEx::CStdioFileEx(LPCTSTR lpszFileName,UINT nOpenFlags)
:CStdioFile(lpszFileName, PreprocessFlags(lpszFileName, nOpenFlags))
{
} BOOL CStdioFileEx::Open(LPCTSTR lpszFileName,UINT nOpenFlags,CFileException* pError /*=NULL*/)
{
PreprocessFlags(lpszFileName, nOpenFlags); return CStdioFile::Open(lpszFileName, nOpenFlags, pError);
} BOOL CStdioFileEx::ReadString(CString& rString)
{
#ifdef _UNICODE
return ReadWideString(rString);
#else
return ReadAnsiString(rString);
#endif
} BOOL CStdioFileEx::ReadWideString(CStringW& rString)
{
_ASSERTE(m_pStream);
rString = L""; // empty string without deallocating if(m_bIsUnicodeText)
{
// If at position 0, discard byte-order mark before reading
if(GetPosition() == 0)
{
wchar_t bom;
Read(&bom, sizeof(wchar_t));
}
const int nMaxSize = 128;
LPWSTR lpsz = rString.GetBuffer(nMaxSize);
LPWSTR lpszResult;
int nLen = 0;
for (;;)
{
lpszResult = fgetws(lpsz, nMaxSize+1, m_pStream);
rString.ReleaseBuffer(); // handle error/eof case
if (lpszResult == NULL && !feof(m_pStream))
{
Afx_clearerr_s(m_pStream);
AfxThrowFileException(CFileException::genericException, _doserrno,
m_strFileName);
} // if string is read completely or EOF
if (lpszResult == NULL ||
(nLen = (int)lstrlenW(lpsz)) < nMaxSize ||
lpsz[nLen-1] == '\n')
break; nLen = rString.GetLength();
lpsz = rString.GetBuffer(nMaxSize + nLen) + nLen;
}
//remove crlf if exist.
nLen = rString.GetLength();
if (nLen > 1 && rString.Mid(nLen-2) == L"\r\n")
{
rString.GetBufferSetLength(nLen-2);
}
return rString.GetLength() > 0;
}
else
{
CStringA ansiString;
BOOL bRetval = ReadAnsiString(ansiString);
//setlocale(LC_ALL, "chs_chn.936");//no need
rString = ansiString;
return bRetval;
}
} BOOL CStdioFileEx::ReadAnsiString(CStringA& rString)
{
_ASSERTE(m_pStream);
rString = ""; // empty string without deallocating if(!m_bIsUnicodeText)
{
const int nMaxSize = 128;
LPSTR lpsz = rString.GetBuffer(nMaxSize);
LPSTR lpszResult;
int nLen = 0;
for (;;)
{
lpszResult = fgets(lpsz, nMaxSize+1, m_pStream);
rString.ReleaseBuffer(); // handle error/eof case
if (lpszResult == NULL && !feof(m_pStream))
{
Afx_clearerr_s(m_pStream);
AfxThrowFileException(CFileException::genericException, _doserrno,
m_strFileName);
} // if string is read completely or EOF
if (lpszResult == NULL ||
(nLen = (int)lstrlenA(lpsz)) < nMaxSize ||
lpsz[nLen-1] == '\n')
break; nLen = rString.GetLength();
lpsz = rString.GetBuffer(nMaxSize + nLen) + nLen;
}
//remove crlf if exist.
nLen = rString.GetLength();
if (nLen > 1 && rString.Mid(nLen-2) == "\r\n")
{
rString.GetBufferSetLength(nLen-2);
}
return rString.GetLength() > 0;
}
else
{
CStringW wideString;
BOOL bRetval = ReadWideString(wideString);
//setlocale(LC_ALL, "chs_chn.936");//no need
rString = wideString;
return bRetval;
}
} // Purpose: Writes string to file either in Unicode or multibyte, depending on whether the caller specified the
// CStdioFileEx::modeWriteUnicode flag. Override of base class function.
void CStdioFileEx::WriteString(LPCTSTR lpsz)
{
#ifdef _UNICODE
WriteWideString(lpsz);
#else
WriteAnsiString(lpsz);
#endif
} void CStdioFileEx::WriteWideString(LPCWSTR lpsz)
{
ASSERT(lpsz != NULL); if (lpsz == NULL)
{
AfxThrowInvalidArgException();
}
if(m_bIsUnicodeText)
{
ASSERT(m_pStream != NULL);
// If writing Unicode and at the start of the file, need to write byte mark
if(GetPosition() == 0)
{
wchar_t cBOM = (wchar_t)UNICODE_BOM;
CFile::Write(&cBOM, sizeof(wchar_t));
}
if (fputws(lpsz, m_pStream) == _TEOF)
AfxThrowFileException(CFileException::diskFull, _doserrno, m_strFileName);
}
else
{
USES_CONVERSION;
WriteAnsiString(CW2A(lpsz));
}
} void CStdioFileEx::WriteAnsiString(LPCSTR lpsz)
{
ASSERT(lpsz != NULL); if (lpsz == NULL)
{
AfxThrowInvalidArgException();
}
if(!m_bIsUnicodeText)
{
ASSERT(m_pStream != NULL);
if (fputs(lpsz, m_pStream) == _TEOF)
AfxThrowFileException(CFileException::diskFull, _doserrno, m_strFileName);
}
else
{
USES_CONVERSION;
WriteWideString(CA2W(lpsz));
}
} UINT CStdioFileEx::PreprocessFlags(const CString& sFilePath, UINT& nOpenFlags)
{
m_bIsUnicodeText = false; // If we have writeUnicode we must have write or writeRead as well
if (nOpenFlags & CStdioFileEx::modeWriteUnicode)
{
ASSERT(nOpenFlags & CFile::modeWrite || nOpenFlags & CFile::modeReadWrite);
m_bIsUnicodeText = true;
}
// If reading in text mode and not creating...
else if (nOpenFlags & CFile::typeText && !(nOpenFlags & CFile::modeCreate) && !(nOpenFlags & CFile::modeWrite ))
{
m_bIsUnicodeText = IsFileUnicode(sFilePath);
} //如果要读写Unicode格式的文本文件, 必须切换到typeBinary方式, 因为这会影响fputws/fgetws的工作方式(具体情况参考MSDN)。
if (m_bIsUnicodeText)
{
nOpenFlags &= ~(CFile::typeText);
nOpenFlags |= CFile::typeBinary;
} return nOpenFlags;
} // Purpose: Determines whether a file is Unicode by reading the first character and detecting
// whether it's the Unicode byte marker.
bool CStdioFileEx::IsFileUnicode(const CString& sFilePath)
{
CFile file;
wchar_t cFirstChar;
CFileException exFile; bool bIsUnicode = false;
// Open file in binary mode and read first character
if (file.Open(sFilePath, CFile::typeBinary | CFile::modeRead, &exFile))
{
// If byte is Unicode byte-order marker, let's say it's Unicode
if (file.Read(&cFirstChar, sizeof(wchar_t)) > 0 && cFirstChar == (wchar_t)UNICODE_BOM)
{
bIsUnicode = true;
} file.Close();
}
else
{
// Handle error here if you like
} return bIsUnicode;
} unsigned long CStdioFileEx::GetCharCount()
{
int nCharSize;
unsigned long nByteCount, nCharCount = 0; if (m_pStream)
{
// Get size of chars in file
nCharSize = m_bIsUnicodeText ? sizeof(wchar_t): sizeof(char); // If Unicode, remove byte order mark from count
nByteCount = (unsigned long)GetLength(); if (m_bIsUnicodeText)
{
nByteCount = nByteCount - sizeof(wchar_t);
} // Calc chars
nCharCount = (nByteCount / nCharSize);
} return nCharCount;
}
C++ writestring 为什么不能写进中文 CStdioFile向无法向文本中写入中文【二】的更多相关文章
- PHP往mysql数据库中写入中文失败
该类问题解决办法就是 在建立数据库连接之后,将该连接的编码方式改为中文. 代码如下: $linkID=@mysql_connect("localhost","root&q ...
- Python: 在CSV文件中写入中文字符
0.2 2016.09.26 11:28* 字数 216 阅读 8053评论 2喜欢 5 最近一段时间的学习中发现,Python基本和中文字符杠上了.如果能把各种编码问题解决了,基本上也算对Pytho ...
- Linux学习笔记之ubuntu如何在vi中写入中文注释
点击左边设置system settings,再点击Language Suppotr 点击Remind Me Later 选择ibus 然后关闭,在终端写入ibus-setup,弹出设置框,选择INPU ...
- qt 文本中显示中文
QTextCodec *codec = QTextCodec::codecForName("utf8");QTextCodec::setCodecForLocale(codec); ...
- java向mysql中写入中文出现乱码
乱码的原因有很多,我遇到的原因是url配置的问题,解决方案: 将: jdbc.url=jdbc:mysql://localhost:3306/XXXX?useUnicode=true&char ...
- CStdioFile的Writestring无法写入中文的问题
解决UNICODE字符集下CStdioFile的Writestring无法写入中文的问题 2009-12-01 23:11 以下代码文件以CStdioFile向无法向文本中写入中文(用notepad. ...
- 使用cstdiofile在vs2010中无法写入中文的问题
在VC2010环境下, 以下代码无法实现使用CStdioFile向文本文件中写入中文(用notepad.exe查看不到写入的中文) CStdioFile file; file.Open(…); fil ...
- mysql5.7中解决中文乱码的问题
在使用mysql5.7时,会发现通过web端向数据库中写入中文后会出现乱码,但是在数据库中直接操作SQL语句插入数据后中文就显示正常,这个问题怎么解决呢?此处不对mysql的数据编码过程和原理进行讲解 ...
- 如何在Ubuntu中安装中文输入法
在使用ubuntu系统时,有的时候总觉得英文输入法不方便操作,总希望能有中文输入法可以辅助操作,那怎样才能在ubuntu中安装中文输入法呢?下面有一种简单的方法可以安装中文输入法. 如何在ubuntu ...
随机推荐
- [BZOJ4016]最短路径树问题
Description 给一个包含n个点,m条边的无向连通图.从顶点1出发,往其余所有点分别走一次并返回. 往某一个点走时,选择总长度最短的路径走.若有多条长度最短的路径,则选择经过的顶点序列字典序最 ...
- 项目发布后 Tomcat中只有web-INF文件夹
这是有文件夹没有加载 解决办法如下
- c++之迭代器失效
1.首先从一到题目开始谈说起迭代器失效.有时我们很自然并且自信地 用下面方法删除vector元素: #include <iostream>#include <stdio.h># ...
- 从U盘安装linux(前人踩坑后人乘凉)
今天踩了一个大坑,网上的教程从u盘安装linux少了一个关键步骤导致我挣扎了两个小时 废话不多说,开始需要准备一些东西 1.从官网下载一个Ubuntu 10.04的镜像 2.一个大于等于1G的支持启动 ...
- linux环境变量 export命令详解
由host $ export DVSDK="${HOME}/ti-dvsdk_dm368-evm_xx_xx_xx_xx"引发的问题 1.${HOME}:首先, HOME 是个变量 ...
- bzoj 1192 鬼谷子的钱袋 数学
1192: [HNOI2006]鬼谷子的钱袋 Time Limit: 10 Sec Memory Limit: 162 MB Description 鬼谷子非常聪明,正因为这样,他非常繁忙,经常有各 ...
- Log4j 2.0 使用说明(1) 之HelloWorld
以下是Log4j2.0的类图,以便大家对2.0有一个整体的理解. 就如我们学习任何一个技术一样,这里我们首先写一个Hello World: 1,新建工程TestLog4j 2,下载Log4j 2.0有 ...
- 实现Promise的first等各种变体
本篇文章主要是想通过ES6中Promise提供的几个方法,来实现诸如first.last.none.any等各种变体方法! 在标准的ES6规范中,提供了Promise.all和Promise.race ...
- Selenium入门练习(二)
自动登录博客园并且退出登录 package TestNG; import org.testng.annotations.Test;import org.testng.annotations.Befor ...
- Windows音频SDK的发展历程
WASAPI is one of several native audio libraries in Windows. PortAudio actually supports five of them ...