这周的任务很简单,就是将一个大的ansi格式的文件,分割成多个Unicode格式的小文件。 但是C++中的文件操作有很多,本来对文件操作就不熟悉的我,再加上各种字符集的转换,真是把我搞得晕头转向。现在理顺下。
文件操作
第一种 利用文件指针
FILE * pf;
char buffer[255];
pf.open("Disk\\ruby.txt");//打开Disk下的ruby.txt
fwrite(buffer,size,count,fp);//这样我们就可以将buffer中的count*size个字符写到fp所指向的文件中了
fread(buffer,size,count,fp);//利用fread函数我们可以将fp中的count*size个字符写到buffer中
fclose(pf);//注意操纵完文件指针一定要关闭
在这里,通过pf指针利用fwrite和fread对文件进行读写操作,都是针对字符串的,也就是char型的。所以要是我们想让他兼容Unicode格式下的宽字符,就要在操作之后,将字符转换为宽字符。具体转换方法我们下面再说。
这里我们可以看到通过pf指针利用fwrite和fread对文件进行读写操作,都是针对字符串的,他的好处是可以直接操作写入和读出文件的字符数目。而且我们可以通过fseek函数,方便的更改文件读写的起点。这在使用起来相当方便。而且它的写入函数可以写入const v.oid *类型。但是唯一的缺点就是它是针对字符串的,所以不能很方便的整行整行的读写数据。
第二种 利用文件流
ifstream in("Disk:\\ruby.txt");//以输入方式打开文件
ofstream out("Disk:\\ruby.txt");//以输出方式打开文件
in<<"I Love You";//向文件写入字符串"I Love You"
out>>i;//从文件输入一个整数值。
out.get(str1,127,'A'); //从文件中读取字符到字符串str1,当遇到字符'A'或读取了127个字符时终止。
in.put('c');//注意这里只能put进一个char型
out.write(str1,strlen(str1));//把字符串str1指向的缓存写 num 个字符到文件中,值得注意的是缓存的类型是 unsigned char *
in.read((unsigned char*)buf,sizeof(n));//从文件中读取 num 个字符到 buf指向的缓存中读取指定个整数,注意类型转换
in.close();
out.close();
if(in.eof()) ShowMessage("已经到达文件尾!");判断文件是否到达结尾。利用.seekg函数可以移动文件指针。
还有类似的fgets()和fread()可以整行的读写。
这里我们看到流,封装了很多函数,我们可以很方便的进行数据常量的输入输出,但是对于数据变量,我们无法方便的写入指定类型的字符(除了cha*r和unsigned char *类型)。
第三种 利用文件句柄
HANDLE hfile;
hfile = createFile();
WriteFile
ReadFile
这里都是针对宽字符集的,对于Unicode很实用,但是他没办法进行文件读写格式,读写个数,和读写位置的控制。
字符集的转换
第一 char * 和 wchar*之间的转换
对于string来说,只要string.c_str就可以取道他的字符串的首地址,但要注意这个指针是个const * char类型
(一) char*转换成wchar*
char * cstr = "北师大dd";
wchar * wstr;
1、求得cstr的字符数(在ansi中1个英文字符占1个字节,1个中文字符占2个字节)
DWORD n = MultiByteToWideChar(CP_OEMCP,NULL,cstr,-1,NULL,0,NULL,FALSE);
2、给wstr开辟空间(在Unicode中1个英文字符占2个字节,1个中文字符占2个字节)
wstr = new wchar[n];
3、转换
MultiByteToWideChar(CP_OEMCP,NULL,cstr,-1,wstr,n,NULL,FALSE);
(二)wchar*转换成char*也是同样步骤,只是将MultiByteToWideChar()换成WideCharToMultiByte(CP_OEMCP,NULL,c_fileName,-1,NULL,0,NULL,FALSE)
第二 int 和 string之间的转换
itoa
第三 字符集ansi和Unicode
WCHAR Unicode字符
PWSTR 指向Unicode字符串的指针
PCWSTR 指向一个恒定的Unicode字符串的指针
对应的ANSI数据类型为CHAR,LPSTR和LPCSTR。
ANSI/Unicode通用数据类型为TCHAR,PTSTR,LPCTSTR。
ANSI 操作函数以str开头 strcpy
Unicode 操作函数以wcs开头 wcscpy
MBCS 操作函数以_mbs开头 _mbscpy
ANSI/Unicode 操作函数以_tcs开头 _tcscpy(C运行期库)
ANSI/Unicode 操作函数以lstr开头 lstrcpy(Windows函数)
所有新的和未过时的函数在Windows2000中都同时拥有ANSI和Unicode两个版本。ANSI版本函数结尾以A表示;Unicode版本函数结尾以W表示。
char 和 wchar函数很相似,但是有不同,要注意区分。
strcpy等是标准ANSI函数,有的人爱用_tXXXX函数,这个问题曾经搞的很混乱。为了统一,有必要把来龙去脉搞清楚。 为了搞清这些函数,就必须理请几种字符类型的写法。char就不用说了,先说一些wchar_t。
wchar_t是Unicode字符的数据类型,它实际定义在<string.h> 里: typedef unsigned short wchar_t;不能使用类似strcpy这样的ANSI C字符串函数来处理wchar_t字符串,必须使用wcs前缀的函数,例如wcscpy。
为了让编译器识别Unicode字符串,必须以在前面加一个 “L”,例如: wchar_t *szTest=L"This is a Unicode string.";