| 项目搜索 |
| |
|
代码片段库:
查看代码片段
浏览
| 提交新的代码片段
| 创建代码包
多字节函数库系列:文件读取:cy_mbrfgetc()
|
类型:
Function |
类别:
Other
|
许可证:
GNU Library Public License |
语言:
C++
|
描述:
单字符读取函数,但支持有“状态改变”的编码系统(如日文的“SJIS/Shift JIS”编码)。功能类似于标准函数:fgetc()
|
该代码片段的版本系列:
片段ID |
下载版本 |
提交时间 |
提交人 |
删除 |
4569 | 0.1 | 2002-06-26 20:46 | renxiao | |
点击"下载版本"来下载该代码片段.
最新版本的代码片段: 0.1
/*-----------------------Own_lib函数库系列 mbrfgetc.cc--------------------------
cy_mbrfgetc() /mbrfgetc.o /libcyfunc.a
描述: 对于多字节文本文件(如中文)的读取, libcylib.a库已提供了cy_mbsrfgets()函数.
按字符逐字读入多字节文本效率并不高, 但为保持"完整", 在此亦提供多字节文本的
逐字读入函数cy_mbrfgetc().
为了提高磁盘读写效率, 建议先用cy_mbsrfgets()读入一行(或许只是行的一部分),
然后再对已读入内存中的字符串进行处理.
顾名思意, 此函数以单个字(可能有多个字节)的方式从文件流中读入文本. 同样, 函
数使用了"mbrtowc()/wcrtomb()"标准库函数(在您的程序开头应setlocale()), 因此,
它能处理有"状态改变"的编码系统(如日文的"SJIS/Shift JIS"编码).
与cy_mbfgetc()函数相比, 参数表中增加了一个"mbstate_t"的设置开关, 默认值为
false(假, 即不再设置函数内部的"mbstate_t"静态变量), 但当第一次读入某种语言
编码的文本文件时, 请置其为true!
与标准函数"fgetc()"类似, 函数返回一个字(一个多字节序列, 末尾已附'\0').
调用函数时: 传递保存读取字的目的地址 | 文件流指针 | "mbstate_t"设置开关 |
和"LC_CTYPE"区域设置字符串(如: "zh_CN.GBK", 默认值为NULL, 表示不改变系统设
置).
下一个函数为重载函数. 增加了返回实际读取字的字节长度的整数引用参数.
dest_str:
保存读入字符串的内存空间的指针(大小: "MB_LEN_MAX + 1").
stream:
FILE结构的文件流指针.
[length]:
返回实际读取字符串的字节数.
state_is = false:
一个处理有"状态改变"的编码文本的开关. 只需初次读取文本时置其为true(真).
locale_ctype = NULL:
读入字串所属的LC_CTYPE区域(语系/编码). 一般程序开头已经设定, 故此可不管它.
返回值:
函数返回读入的多字节字符(单字节字符串). 当有错误时, 返回NULL.
注意! 传入区域字符串后函数将临时改变系统"LC_CTYPE"的设置. 在函数退出时才恢复其
原有的设置.
函数内部处理采用"mbrtowc()/wcrtomb()", 故其应当也适用于无状态改变的编码系
统(如中文).
作者: 任逍 |2002.05.11.
版权: GNU General (Library) Public License (GPL/LGPL)
* 编辑器: vim-6.0 |操作系统: TurboLinux7.0简体中文版 *
------------------------------------------------------------------------------*/
#include <stdio.h> // usr for fgets()
#include <stdlib.h> // usr for mbs* and others.
#include <limits.h> // usr for MB_LEN_MAX --当前多字节环境下每字最大字节长.
#include <locale.h> // usr for setlocale().--函数提供改变环境"LC_CTYPE"的机会
#include <string.h> // usr for memset()
#include <wchar.h> // usr for mbsrtowcs()|wcsrtombs() |mbrtowc()|wcrtomb()
#include "cyinclude/cyfget.h"
char * cy_mbrfgetc(char * dest_str, FILE * stream,
bool state_is = false, const char * locale_ctype = NULL)
{
long fpos_before;
if ( (fpos_before = ftell(stream)) == -1 ) // 获取读取前的文件流指针位置
return NULL;
int num = MB_LEN_MAX;
char tmp_chars[num + 1]; // 每字所需的最大可能空间(字节数), 临时存放用
wchar_t tmp_wchar;
size_t chars_length;
if (! fgets(tmp_chars, num + 1, stream)) // 接收最大限定数量的输入字符串
return NULL;
bool locale_check = false;
char* locale_original = setlocale(LC_CTYPE, NULL); // LC_CTYPE原来的值
if (locale_ctype)
{
setlocale(LC_CTYPE, locale_ctype);
locale_check = true;
}
static mbstate_t state_towc; // 设置记录字符串编码"状态"的静态变量
static mbstate_t state_tomb; // 设置记录字符串编码"状态"的静态变量
if (state_is)
memset(&state_towc, '\0', sizeof(mbstate_t));
memset(&state_tomb, '\0', sizeof(mbstate_t));
if (mbrtowc(&tmp_wchar, tmp_chars, num, &state_towc) == (size_t)-1)
return NULL;
if ( (chars_length = wcrtomb(dest_str, tmp_wchar, &state_tomb)) == (size_t)-1 )
return NULL;
dest_str[chars_length] = '\0';
if (locale_check)
setlocale(LC_CTYPE, locale_original);
if (fseek(stream, fpos_before + chars_length, SEEK_SET))
return NULL; // 重置文件流指针, 当有错误时, 返回NULL
return dest_str;
}
//-----------------------------------------------------------------------------
// 上一函数的重载函数
char * cy_mbrfgetc(char * dest_str, FILE * stream, int & length,
bool state_is = false, const char * locale_ctype = NULL)
{
long fpos_before;
if ( (fpos_before = ftell(stream)) == -1 ) // 获取读取前的文件流指针位置
return NULL;
int num = MB_LEN_MAX;
char tmp_chars[num + 1]; // 每字所需的最大可能空间(字节数), 临时存放用
wchar_t tmp_wchar;
size_t chars_length;
if (! fgets(tmp_chars, num + 1, stream)) // 接收最大限定数量的输入字符串
return NULL;
bool locale_check = false;
char* locale_original = setlocale(LC_CTYPE, NULL); // LC_CTYPE原来的值
if (locale_ctype)
{
setlocale(LC_CTYPE, locale_ctype);
locale_check = true;
}
static mbstate_t state_towc; // 设置记录字符串编码"状态"的静态变量
static mbstate_t state_tomb; // 设置记录字符串编码"状态"的静态变量
if (state_is)
memset(&state_towc, '\0', sizeof(mbstate_t));
memset(&state_tomb, '\0', sizeof(mbstate_t));
if (mbrtowc(&tmp_wchar, tmp_chars, num, &state_towc) == (size_t)-1)
return NULL;
if ( (chars_length = wcrtomb(dest_str, tmp_wchar, &state_tomb)) == (size_t)-1 )
return NULL;
dest_str[chars_length] = '\0';
length = chars_length; //!.引用返回该字符的字节数. (较前一函数只多此一句).
if (locale_check)
setlocale(LC_CTYPE, locale_original);
if (fseek(stream, fpos_before + chars_length, SEEK_SET))
return NULL; // 重置文件流指针, 当有错误时, 返回NULL
return dest_str;
}
如果您修改了一个代码片段并且觉得很应该让别人共享,您可以把这作为这个代码片段的最新版本提交上来. |
|