c/c++开发,无可避免的文件访问开发案例

news2024/11/26 5:36:10

一、缓存文件系统

        ANSI C标准中的C语言库提供了fopen, fclose, fread, fwrite, fgetc, fgets, fputc, fputs, freopen, fseek, ftell, rewind等标准函数,这些函数在不同的操作系统中应该调用不同的内核API,从而支持开发者跨平台实现对文件的访问。

        在Linux环境下,fopen是对open的封装,open系列是 POSIX 定义的,是UNIX系统里的system call。Linux环境下,一切设备皆是文件,一切设备皆是以文件的形式进行操作,如网络套接字、硬件设备等,对于Linux系统内核而言,文本文件和二进制代码文件并无区别,而open、write、read这些函数通过操作系统的功能对文件进行读写,是系统级的输入输出,它不设文件结构体指针,只能读写二进制文件。

        不同于open、write这些函数,fopen 、fread这些函数是标准的C库函数,更具有可移植性,几乎可以可移植到任何操作系统。在实际项目中,尤其是上位应用中,一般是用fopen 、fread这些函数来操作普通文件,fopen返回一个文件指针,就可以利用文件指针操作文件,其可以读取一个结构数据,并支持缓冲IO。由于支持缓存IO,因此fopen 、fread这些函数在处理稍大的文件时,系统自动分配缓存,则读出此文件等操作要比open、write这些函数效率高。

        因此,fopen 、fread是属于缓冲文件系统,系统在内存中开辟一个“缓冲区”,为程序里每一个文件使用,当执行读文件操作时,从磁盘文件将数据先读入内存“缓冲区”,装满后再从内存“缓 冲区”依次读入接收的变量。执行写文件操作时,也是先将数据写入内存“缓冲区”,待内存“缓冲区”装满后再写入文件。

        fopen 函数返回的是一个FILE结构指针,借助于文件结构体指针FILE *就可以实现对文件管理,通过文件指针对文件进行访问,即可以读写字符、字符串、格式化数据,也可以读写二进制数据。

        fopen 函数原型是:FILE *fopen(const char* file, const char* model),可以指定一个文件路径来打开一个文件,成功时返回非NULL的FILE *。fclose, fread, fwrite, fgetc, fgets, fputc, fputs等函数都是基于该文件指针进行操作。

二、文件访问开发设计

        2.1 文件接口服务设计

        本文将通过fopen, fclose, fread, fwrite, fgetc, fgets等系列函数,实现跨windows和linux的文件访问,进行数据读取、写入,并在此基础上,提供对文件内容行读取与写入、列分割等快捷功能,同时实现都目录及文件的创建、存在判定、删除、重命名等操作。

        例如:

//文件操作相关
bool writeToFile(const char *ptr,const std::string& path, const std::string& mode);//写入一段内容
bool writeListInfo(std::vector<std::string> list,const std::string path);//写入多行内容
bool readFromFile(char *ptr, int &size, int buf_size,const std::string& path, const std::string& mode);//读取一段内容
bool readListInfo(std::vector<std::vector<std::string> > &list,const std::string path);//读取多行内容
bool readListInfo(std::vector<std::vector<std::string> > &list,const std::string path);//读取多行内容,每行按空格分割

//目录相关
bool createDir(std::string _dir);        //创建目录
bool isExistDir(std::string _dir);       //判断指定目录是否存在
bool getCurrentDir(char* dir_, int len_);//获取当前目录路径

//文件相关
void renameFile(const std::string& _oldName, const std::string& _newName);//重命名文件
void removeFile(const std::string& _Name);        //删除文件
bool isExist(std::string file);                    //文件(绝对及相对路径名)是否存在
bool isExist(std::string dir,std::string file);    //某目录下某文件是否存在

        文件的读写伪代码如下:

//打开
FILE *m_fil = ::fopen(path,mode);
//读取
int size = fread(buf, static_cast<int>(sizeof(char)), (size_t)buf_size,m_fil);
//写入
::fwrite(buf, static_cast<int>(sizeof(char)), buf_len,m_fil );
//循环读取每行数据
while(NULL!=::fgets(buf,buf_size,m_fil))

        在目录及文件名处理方面伪代码如下:

//获取路径
char* dir = getcwd(dir_, len_);
//访问目录-linux
DIR* dfd = opendir(_dir.c_str());
//访问目录-win
bool ret = _access(_dir.c_str(),0);
//创建目录(win _mkdir)
int ret = mkdir(_dir.c_str(), S_IRWXU | S_IRWXG | S_IRWXO);


//文件是否存在-win
_finddata_t fileInfo;
intptr_t hFile = _findfirst(file,&fileInfo);
//文件是否存在-Linux是否能打开文件来判断
::fopen
//重命名文件
int ret = rename(_oldName,_newName);
//删除文件
int ret = remove(_Name);

        行内容按空格或“.”划分:

//将采用空格间隔的字符串划分成子字符串集
std::string buffer;                    // Have a buffer string
std::stringstream _lineStr(_lineInfo); // Insert the string into a stream
std::vector<std::string> _lineList;    // Create vector to hold our words
while(_lineStr >> buffer)
{
    _lineList.push_back(buffer);
}

//将采用","间隔的字符串划分成子字符串集
void pyfree::getNumberFromStr(std::vector<std::string> &ids, std::string idsStr)
{
	if(""==idsStr||"NULL"==idsStr)
		return;
	std::string id = "";
	for(unsigned int i=0,idSize= static_cast<unsigned int>(idsStr.size()); i<idSize; i++)
	{
		if(','==idsStr[i])
		{//use str ',' to dirve the idsStr;
			if(""!=id)
			{
				ids.push_back(id);
				id.clear();
				id = "";
			}else{
				ids.push_back(id);
			}
		}else if(i==(idSize-1))
		{
			if(""!=id)
			{
				ids.push_back(id);
				id.clear();
				id = "";
			}
		}else{
			id.push_back(idsStr[i]);
		}
	}
}

        在实际项目中,往往会遇到中文情况,尤其是在linux系统下,不少文件是采用ascii或gbk、gb2312等存储编码格式,但在程序内处理数据是大多是采用utf-8编码格式,因此必要时还需要对读取到的内容做编码格式转换。

//增加codef类型参数来确定是否进行编码格式转换
bool readListInfo(std::vector<std::vector<std::string> > &list,const std::string path,int codef=0);//读取多行内容
bool readListInfo(std::vector<std::vector<std::string> > &list,const std::string path,int codef=0);//读取多行内容,每行按空格分割

        2.2 工程及代码设计

        创建项目目录结构如下:

myfile_test
    bin
    build_win           //win编译过程文件路径
    build_linux         //Linux编译过程文件目录
    src                 //文件接口源码
    test                //接口调用示例
    CMakeLists.txt      //cmake工程配置文件
    编译指令.txt         //编辑及运行命令

        在src目录下创建File.h/cpp源文件,File.h设计如下,File.cpp见附录:

#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000

#ifndef _FILE_H_
#define _FILE_H_
/***********************************************************************
  *Copyright 2023-02-07, pyfree
  *
  *File Name       : File.h
  *File Mark       : 
  *Summary         : 
  *文本读写函数类
  *
  *Current Version : 1.00
  *Author          : pyfree
  *FinishDate      :
  *
  *Replace Version :
  *Author          :
  *FinishDate      :

 ************************************************************************/
#include <string>
#include <vector>
#include <stdio.h>

namespace pyfree
{
	/**
	 * 向指定文件写入数据
	 * @param ptr {const char*} 待写入内容
	 * @param path {string} 文件名
	 * @param mode {string} 写入模式,等同于fopen或open函数的写入模式
	 * @return {bool} 
	 */
	bool writeToFile(const char *ptr,const std::string& path, const std::string& mode);
	/**
	 * 向指定文件追写数据
	 * @param list {vector} 待写入内容容器,每项作为一行写入
	 * @param path {string} 文件名
	 * @return {bool} 
	 */
	bool writeListInfo(std::vector<std::string> list,const std::string path);
	/**
	 * 从指定文件读取数据
	 * @param ptr {char*} 待读取内容指针
	 * @param size {int&} 实际读取大小
	 * @param buf_size {int} 待读取指针存储空间大小
	 * @param list {vector} 待写入内容容器,每项作为一行写入
	 * @param path {string} 文件名
	 * @param mode {string} 读取模式,等同于fopen或open函数的读取模式
	 * @return {bool} 
	 */
	bool readFromFile(char *ptr, int &size, int buf_size,const std::string& path, const std::string& mode);
	/**
	 * 从指定文件中读取文件每一行的字符串,如果行中存在空格,划分该行字符串,并装在到容器中
	 * @param list {vector<vector>} 读取内容容器,每一行作为一项载入容器,每行内容分割后容器装载
	 * @param path {string} 文件名
	 * @param codef {int} 读取时编码转换{1:g2u,2:a2u,其他不做处理}
	 * @return {bool} 
	 */
	bool readListInfo(std::vector<std::vector<std::string> > &list,const std::string path,int codef=0);
	/**
	 * 从指定文件中读取文件每一行的字符串,如果行中存在","间隔,划分该行字符串,并装在到容器中
	 * @param list {vector<vector>} 读取内容容器,每一行作为一项载入容器,每行内容分割后容器装载
	 * @param path {string} 文件名
	 * @param codef {int} 读取时编码转换{1:g2u,2:a2u,其他不做处理}
	 * @return {bool} 
	 */
	bool readListInfo_dot(std::vector<std::vector<std::string> > &list,const std::string path,int codef=0);
	/**
	 * 从指定文件中读取文件每一行的字符串并装在到容器中
	 * @param list {vector} 读取内容容器,每一行作为一项载入容器
	 * @param path {string} 文件名
	 * @param codef {int} 读取时编码转换{1:g2u,2:a2u,其他不做处理}
	 * @return {bool} 
	 */
	bool readListInfo(std::vector<std::string> &list,const std::string path,int codef=0);
	/**
	 * 将采用","间隔的字符串划分成子字符串集,被readListInfo_dot调用
	 * @param ids {vector} 读取内容容器
	 * @param idsStr {string} 被检查字符串
	 * @return {void} 
	 */
	void getNumberFromStr(std::vector<std::string> &ids, std::string idsStr);
	/**
	 * 从指定文件目录下读取指定扩展名的文件名,返回结果包含扩展名
	 * @param directory {string} 文件目录
	 * @param extName {string} 扩展名
	 * @param fileNames {vector} 读取结果
	 * @return {bool} 是否成功
	 */
	void getAllFileName_dot(const std::string& directory, const std::string& extName, std::vector<std::string>& fileNames);
	/**
	 * 从指定文件目录下读取指定扩展名的文件名,返回结果不包含扩展名
	 * @param directory {string} 文件目录
	 * @param extName {string} 扩展名
	 * @param fileNames {vector} 读取结果
	 * @return {bool} 是否成功
	 */
	void getAllFileName(const std::string& directory, const std::string& extName, std::vector<std::string>& fileNames);
	/**
	 * 从指定文件目录下读取指定扩展名的文件名,被getAllFileName_dot和getAllFileName调用
	 * @param directory {string} 文件目录
	 * @param extName {string} 扩展名
	 * @param fileNames {vector} 读取结果
	 * @param f {bool} 是否包含扩展名
	 * @return {bool} 是否成功
	 */
	void getAllFileNamePrivate(const std::string& directory
		, const std::string& extName
		, std::vector<std::string>& fileNames
		, bool f=false);
	/**
	 * 读取文件修改时间
	 * @param file_path {string} 文件名(全路径)
	 * @return {uint} 时间(time_t)
	 */
	unsigned int getFileModifyTime(const std::string file_path);
	/**
	 * 重命名文件
	 * @param _oldName {string} 旧文件名
	 * @param _newName {string} 新文件名
	 * @return {void}
	 */
	void renameFile(const std::string& _oldName, const std::string& _newName);
	/**
	 * 删除文件
	 * @param _Name {string} 文件名(全路径)
	 * @return {void}
	 */
	void removeFile(const std::string& _Name);
	/**
	 * 文件是否存在
	 * @param file {string} 文件名(全路径)
	 * @return {bool}
	 */
	bool isExist(std::string file);
	/**
	 * 文件在指定目录下是否存在
	 * @param dir {string} 指定目录
	 * @param file {string}
	 * @return {bool}
	 */
	bool isExist(std::string dir,std::string file);
	/**
	 * 将多很节点的xml表述文件重新批量重写为单根节点的xml文件集
	 * @param _xmlFile {string} 文件名
	 * @param _xmlDir {string} 目录
	 * @param _xmlDiv {string} 根节点名
	 * @param utfFlag {bool} 是否utf编码
	 * @return {void}
	 */
	void divXmlFile(std::string _xmlFile,std::string _xmlDir,std::string _xmlDiv,bool utfFlag);
	/**
	 * 创建文件目录
	 * @param _dir {string} 目录名
	 * @return {bool}
	 */
	bool createDir(std::string _dir);
	/**
	 * 文件目录是否存在
	 * @param _dir {string} 目录名
	 * @return {bool}
	 */
	bool isExistDir(std::string _dir);
	/**
	 * 获取程序当前所在目录
	 * @param dir_ {char*} 目录名
	 * @return {bool}
	 */
	bool getCurrentDir(char* dir_, int len_);
};

#endif //_FILE_H_

        在src目录下创建strTrim.h,用来去除字符串前后空格。

#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000

#ifndef _STRTRIM_H_
#define _STRTRIM_H_
/***********************************************************************
  *Copyright 2023-02-08, pyfree
  *
  *File Name       : strTrim.h
  *File Mark       : 
  *Summary         : 
  *字符串前后空格处置函数
  *
  *Current Version : 1.00
  *Author          : pyfree
  *FinishDate      :
  *
  *Replace Version :
  *Author          :
  *FinishDate      :

 ************************************************************************/

#include <string>
#include <vector>
#include <algorithm>
#include <functional>

namespace pyfree
{
/**
 * 删除字符串前面的空格
 * @param ss {string&} 传入字符串
 * @return {string& } 返回字符串
 */
inline std::string& lTrim(std::string &ss)
{
	ss.erase(0, ss.find_first_not_of(" \t")); //
    return  ss;
}
/**
 * 删除字符串后面的空格
 * @param ss {string&} 传入字符串
 * @return {string& } 返回字符串
 */
inline  std::string& rTrim(std::string &ss)
{
	ss.erase(ss.find_last_not_of(" \t") + 1); //
    return   ss;
}
/**
 * 删除字符串前面和后面的空格
 * @param ss {string&} 传入字符串
 * @return {string& } 返回字符串
 */
inline  std::string& trim(std::string &st)
{
    lTrim(rTrim(st));
    return   st;
}
/**
 * 擦除字符串后面的结束字符
 * @param ss {string&} 传入字符串
 * @return {string& } 返回字符串
 */
inline void trimEnd(std::string &dir)
{
    if(dir.empty()){
        return;
    }
	//some line is NULL
	if(dir.size()==1){
		return;
	}
    while(dir[dir.length()-1] == '\n'
		|| dir[dir.length()-1] == '\r'
		|| dir[dir.length()-1] == '\t')
    {
        dir = dir.substr(0,dir.size()-1);
    }
};

};

#endif //

        在src目录下,创建strchange.h/cpp,用来处理字符编码格式转换,strchange.h内容如下,strchange.cpp见附录。

#ifdef WIN32
#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000
#endif

#ifndef _STR_CHANGE_H_
#define _STR_CHANGE_H_

/***********************************************************************
  *Copyright 2023-02-07, pyfree
  *
  *File Name       : strchange.h
  *File Mark       : 
  *Summary         : 
  *字符编码相关函数集
  *
  *Current Version : 1.00
  *Author          : pyfree
  *FinishDate      :
  *
  *Replace Version :
  *Author          :
  *FinishDate      :

 ************************************************************************/

#include <string>

namespace pyfree
{
#ifdef WIN32
//UTF-8 to Unicode
std::wstring Utf82Unicode(const std::string& utf8string);
//unicode to ascii
std::string WideByte2Acsi(std::wstring& wstrcode);
//ascii to Unicode
std::wstring Acsi2WideByte(std::string& strascii);
//Unicode to Utf8
std::string Unicode2Utf8(const std::wstring& widestring);
//
std::wstring stringToWstring(const std::string& str);
//
std::string wstringToString(const std::wstring& wstr);
#endif

#ifdef __linux__
int code_convert(char *from_charset,char *to_charset,char *inbuf,size_t inlen,char *outbuf,size_t outlen);
int u2g(char *inbuf,int inlen,char *outbuf,int outlen);
int g2u(char *inbuf,size_t inlen,char *outbuf,size_t outlen);
int u2a(char *inbuf,int inlen,char *outbuf,int outlen);
int a2u(char *inbuf,int inlen,char *outbuf,int outlen);
int u2k(char *inbuf,int inlen,char *outbuf,int outlen);
int k2u(char *inbuf,int inlen,char *outbuf,int outlen);
#endif

//utf-8 to ascii
std::string UTF_82ASCII(std::string& strUtf8Code);
//ascii to Utf8
std::string ASCII2UTF_8(std::string& strAsciiCode);
};

#endif //STRCHANGE_HPP

        在str目录下,创建pfunc_print.h,通过宏定义用来打印运行日志信息。

#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000

#ifndef _PFUNC_PRINT_H_
#define _PFUNC_PRINT_H_
/***********************************************************************
  *Copyright 2022-11-06, pyfree
  *
  *File Name       : pfunc_print.h
  *File Mark       : 
  *Summary         : 打印输出通用宏定义
  *
  *Current Version : 1.00
  *Author          : pyfree
  *FinishDate      :
  *
  *Replace Version :
  *Author          :
  *FinishDate      :

 ************************************************************************/
typedef  enum PrintLevel
{  
	LL_NOTICE 	= 1, 	//一般输出
	LL_WARNING 	= 2, 	//告警输出
	LL_TRACE 	= 3,	//追踪调试
	LL_DEBUG 	= 4,	//软件bug
	LL_FATAL 	= 5		//致命错误
}PrintLevel;

#define Print_NOTICE(log_fmt,...) \
	do{ \
		printf("L(%d)[%s:%d][%s] \n"log_fmt"\n", LL_NOTICE,__FILE__, __LINE__, __FUNCTION__, ##__VA_ARGS__); \
	}while (0) 

#define Print_WARN(log_fmt,...) \
	do{ \
		printf("L(%d)[%s:%d][%s] \n"log_fmt"\n", LL_WARNING, __FILE__, __LINE__, __FUNCTION__, ##__VA_ARGS__); \
	}while (0) 

#define Print_TRACE(log_fmt,...) \
	do{ \
		printf("L(%d)[%s:%d][%s] \n"log_fmt"\n", LL_TRACE,__FILE__, __LINE__, __FUNCTION__, ##__VA_ARGS__); \
	}while (0) 

#define Print_DEBUG(log_fmt,...) \
	do{ \
		printf("L(%d)[%s:%d][%s] \n"log_fmt"\n", LL_DEBUG, __FILE__, __LINE__, __FUNCTION__, ##__VA_ARGS__); \
	}while (0) 

#define Print_FATAL(log_fmt,...) \
	do{ \
		printf("L(%d)[%s:%d][%s] \n"log_fmt"\n",LL_FATAL, __FILE__, __LINE__, __FUNCTION__, ##__VA_ARGS__); \
	}while (0) 


#endif

        在test目录下,创建main.cpp,File IO模块调用示例程序

#include "File.h"
#include "pfunc_print.h"

int main(int argc, char* argv[])
{
	std::string dir_ 		= "test";
	std::string file_name 	= "test.txt";
	std::string file_ 		= dir_ + "/" + file_name;
	std::string comment_ 	= "test\n";//写入信息需要自行加"\n",是因为实际项目使用中,有时写入数据需要连续性
	std::vector<std::string> comments_ ;
	comments_.push_back("test1 test10\n");
	comments_.push_back("test2,test20\n");
	comments_.push_back("test3,test30\n");
	//
	char cur_dir_buf[128]={0};
	bool ret = pyfree::getCurrentDir(cur_dir_buf,128);//获取当前目录
	if(!ret)
	{
		Print_DEBUG("getCurrentDir fail!\n");
	}else{
		Print_NOTICE("CurrentDir is %s!\n",cur_dir_buf);
	}
	//目录创建测试
	ret = pyfree::createDir(dir_);//在当前目录创建子目录:dir_
	if(!ret)
	{
		Print_DEBUG("createDir %s fail!\n",dir_.c_str());
	}else{
		Print_NOTICE("createDir %s success!\n",dir_.c_str());
	}
	//目是否存在
	ret = pyfree::isExistDir(dir_);//判断子目录dir_是否存在(是否创建成功)
	if(!ret)
	{
		Print_DEBUG("Dir %s is not exist!\n",dir_.c_str());
	}else{
		Print_NOTICE("Dir %s is exist!\n",dir_.c_str());
	}
	//单段内容写入测试
	ret = pyfree::writeToFile(comment_.c_str(),file_,"w");//重新写入,file_不存在将新建
	if(!ret)
	{
		Print_DEBUG("writeToFile %s to %s fail!\n"
			,comment_.c_str(),file_.c_str());
	}else{
		Print_NOTICE("writeToFile %s to %s success!\n"
			,comment_.c_str(),file_.c_str());
	}
	//指定文件路径名判断
	ret = pyfree::isExist(file_);//判断文件file_是否存在(或是否创建成功)
	if(!ret)
	{
		Print_DEBUG("file_path %s is not exist!\n",file_.c_str());
	}else{
		Print_NOTICE("file_path %s is exist!\n",file_.c_str());
	}
	//指定目录及文件名判断
	ret = pyfree::isExist(dir_,file_name);//当前目录的子目录dir_下是否存在文件名file_name
	if(!ret)
	{
		Print_DEBUG("Dir %s file %s is not exist!\n",dir_.c_str(),file_name.c_str());
	}else{
		Print_NOTICE("Dir %s file %s is exist!\n",dir_.c_str(),file_name.c_str());
	}
	//多行写入测试
	ret = pyfree::writeListInfo(comments_,file_);	//追加写入一组内容
	if(!ret)
	{
		Print_DEBUG("writeListInfo to %s fail!\n"
			, file_.c_str());
	}else{
		Print_NOTICE("writeListInfo to %s success!\n"
			, file_.c_str());
	}
	//文件内容读取测试
	char buf[512]={0};
	int readLen = 0;
	ret = pyfree::readFromFile(buf,readLen,512,file_,"r");//从文件读取指定长度数据
	if(!ret)
	{
		Print_DEBUG("readFromFile from %s fail!\n"
			, file_.c_str());
	}else{
		Print_NOTICE("readFromFile from %s:\n%s\n"
			, file_.c_str(),buf);
	}
	//行读取测试
	std::vector<std::string> list;
	ret = pyfree::readListInfo(list,file_);//从文件按行读取数据
	if(!ret)
	{
		Print_DEBUG("readListInfo from %s fail!\n"
			, file_.c_str());
	}else{
		Print_NOTICE("readListInfo from %s success[%d]:"
			, file_.c_str(),(int)list.size());
		for(unsigned int i=0; i<list.size(); i++){
			printf("row[%u]:%s\n",i,list.at(i).c_str());
		}
	}
	//空格间隔测试
	std::vector<std::vector<std::string> > lists;//从文件按行、列读取数据,列按空格分割
	ret = pyfree::readListInfo(lists,file_);
	if(!ret)
	{
		Print_DEBUG("readListInfo from %s fail!\n"
			, file_.c_str());
	}else{
		Print_NOTICE("readListInfo from %s success[%d]:"
			, file_.c_str(),(int)lists.size());
		for(unsigned int i=0; i<lists.size(); i++)
		{
			for(unsigned int j=0; j<lists.at(i).size(); j++){
				printf("row[%u] col[%u]:%s",i,j,lists.at(i).at(j).c_str());
			}
			printf("\n");
		}
	}
	//,间隔测试
	lists.clear();
	ret = pyfree::readListInfo_dot(lists,file_);//从文件按行、列读取数据,列按","分割
	if(!ret)
	{
		Print_DEBUG("readListInfo from %s fail!\n"
			, file_.c_str());
	}else{
		Print_NOTICE("readListInfo from %s success[%d]:"
			, file_.c_str(),(int)lists.size());
		for(unsigned int i=0; i<lists.size(); i++)
		{
			for(unsigned int j=0; j<lists.at(i).size(); j++){
				printf("row[%u] col[%u]:%s",i,j,lists.at(i).at(j).c_str());
			}
			printf("\n");
		}
	}
	std::vector<std::string> fileNames;
	pyfree::getAllFileName(dir_,"txt",fileNames);//获取子目录dir_下的所有txt格式文件名,文件名不带扩展名
	if(fileNames.empty())
	{
		Print_DEBUG("getAllFileName from %s fail!\n"
			, dir_.c_str());
	}else{
		Print_NOTICE("getAllFileName from %s success[%d]:"
			, dir_.c_str(),(int)fileNames.size());
		for(unsigned int i=0; i<fileNames.size(); i++)
		{
			printf("fileName[%u]:%s \n",i,fileNames.at(i).c_str());
		}
	}
	fileNames.clear();
	pyfree::getAllFileName_dot(dir_,"txt",fileNames);//获取子目录dir_下的所有txt格式文件名,文件名带扩展名
	if(fileNames.empty())
	{
		Print_DEBUG("getAllFileName_dot from %s fail!\n"
			, dir_.c_str());
	}else{
		Print_NOTICE("getAllFileName_dot2 from %s success[%d]:"
			, dir_.c_str(),(int)fileNames.size());
		for(unsigned int i=0; i<fileNames.size(); i++)
		{
			printf("fileName[%u]:%s \n",i,fileNames.at(i).c_str());
		}
	}
    dir_ = "test_s";
	//行读取测试,ANSI格式
	list.clear();
	file_= dir_+"/"+"test1.ini";
	ret = pyfree::readListInfo(list,file_,2);//从文件按行读取数据
	if(!ret)
	{
		Print_DEBUG("readListInfo ANSI fomat from %s fail!\n"
			, file_.c_str());
	}else{
		Print_NOTICE("readListInfo ANSI fomat from %s success[%d]:"
			, file_.c_str(),(int)list.size());
		for(unsigned int i=0; i<list.size(); i++){
			printf("row[%u]:%s\n",i,list.at(i).c_str());
		}
	}
	//行读取测试,GB格式
	list.clear();
	file_= dir_+"/"+"test2.ini";
	ret = pyfree::readListInfo(list,file_,1);//从文件按行读取数据
	if(!ret)
	{
		Print_DEBUG("readListInfo GB fomat from %s fail!\n"
			, file_.c_str());
	}else{
		Print_NOTICE("readListInfo GB fomat from %s success[%d]:"
			, file_.c_str(),(int)list.size());
		for(unsigned int i=0; i<list.size(); i++){
			printf("row[%u]:%s\n",i,list.at(i).c_str());
		}
	}
	return 0;
}

        2.3 编译及测试

        完成后,项目文件结构如下:

myfile_test
    bin
    build_win           //win编译过程文件路径
    build_linux         //Linux编译过程文件目录
    src                 //文件接口源码
        File.h
        File.cpp
        pfunc_print.h
        strTrim.h
        strchange.h
        strchange.cpp
    test                //接口调用示例
        main.cpp
    CMakeLists.txt      //cmake工程配置文件
    编译指令.txt         //编辑及运行命令

        CMakeLists.txt内容如下,基于cmake+vs(win)或+g++(linux)编译工具:

# CMake 最低版本号要求
cmake_minimum_required (VERSION 2.8)
# 项目信息
project (file_test)
#
if(WIN32)
    message(STATUS "windows compiling...")
    add_definitions(-D_PLATFORM_IS_WINDOWS_)
	set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} /MT")
	set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} /MTd")
	set(WIN_OS true)
else(WIN32)
    message(STATUS "linux compiling...")
    add_definitions( -D_PLATFORM_IS_LINUX_)
    add_definitions("-Wno-invalid-source-encoding")
    set(UNIX_OS true)
    set(_DEBUG true)
    
endif(WIN32)

#
set(EXECUTABLE_OUTPUT_PATH ${PROJECT_SOURCE_DIR}/bin)

# 指定源文件的目录,并将名称保存到变量
SET(source_h
    #
	${PROJECT_SOURCE_DIR}/src/pfunc_print.h
	${PROJECT_SOURCE_DIR}/src/strTrim.h
	${PROJECT_SOURCE_DIR}/src/strchange.h
	${PROJECT_SOURCE_DIR}/src/File.h
  )
  
SET(source_cpp
    #
	${PROJECT_SOURCE_DIR}/src/strchange.cpp
	${PROJECT_SOURCE_DIR}/src/File.cpp
	${PROJECT_SOURCE_DIR}/test/main.cpp
  )
  
#头文件目录
include_directories(${PROJECT_SOURCE_DIR}/src)

if (${UNIX_OS})

add_definitions(
  "-W"
  "-fPIC"
  "-Wall"
  # "-Wall -g"
  "-Werror"
  "-Wshadow"
  "-Wformat"
  "-Wpointer-arith"
  "-D_REENTRANT"
  "-D_USE_FAST_MACRO"
  "-Wno-long-long"
  "-Wuninitialized"
  "-D_POSIX_PTHREAD_SEMANTICS"
  "-DACL_PREPARE_COMPILE"
  "-Wno-unused-parameter"
  "-fexceptions"
  )
  set(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} -O0")

link_directories()
# 指定生成目标
add_executable(file_test ${source_h} ${source_cpp} )
#link
target_link_libraries(file_test 
  # -lpthread -pthread
   -lz -lrt -ldl
)

endif(${UNIX_OS})

if (${WIN_OS})

set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /wd4819")

add_definitions(
  "-D_CRT_SECURE_NO_WARNINGS"
  "-D_WINSOCK_DEPRECATED_NO_WARNINGS"
  "-DNO_WARN_MBCS_MFC_DEPRECATION"
  "-DWIN32_LEAN_AND_MEAN"
)

link_directories()

if (CMAKE_BUILD_TYPE STREQUAL "Debug")

set(CMAKE_RUNTIME_OUTPUT_DIRECTORY_DEBUG ${PROJECT_SOURCE_DIR}/bin)
# 指定生成目标
add_executable(file_testd ${source_h} ${source_cpp})

else(CMAKE_BUILD_TYPE)

set(CMAKE_RUNTIME_OUTPUT_DIRECTORY_RELEASE ${PROJECT_SOURCE_DIR}/bin)
# 指定生成目标
add_executable(file_test ${source_h} ${source_cpp})

endif (CMAKE_BUILD_TYPE)

endif(${WIN_OS})

        编译指令如下:

win:
cd myfile_test && mkdir build_win && cd build_win
cmake -G "Visual Studio 14 2015 Win64" -DCMAKE_BUILD_TYPE=Release .. -Wno-dev
#vs 命令窗口
msbuild file_test.sln /p:Configuration="Release" /p:Platform="x64"

linux:
cd file_test && mkdir build_linux && cd build_linux
cmake ..
make

        按上述指令编译,测试如下:

      先在bin目录下创建test_s文件夹,并在该子目录创建test1.ini文件,该文件编码格式为ANSI格式,写上一些内容;在该子目录创建test2.ini文件,该文件编码格式为 GB格式,写上一些中文内容。

        启动程序测试如下:

 三、源码附录

        File.cpp

#include "File.h"

#include <stdarg.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sstream>
#ifdef WIN32
#include <io.h>
#include <windows.h>
#include <direct.h>

#define getcwd _getcwd
#endif
#ifdef linux
#include <string.h>
#include <errno.h>
#include <dirent.h>
#include <unistd.h>
#endif

#include "strchange.h"
#include "strTrim.h"
#include "pfunc_print.h"

bool pyfree::writeToFile(const char *ptr,const std::string& path, const std::string& mode)
{
	FILE *m_fil = NULL;
	m_fil = ::fopen(path.c_str(),mode.c_str());
	if(NULL!=m_fil)
	{
		size_t size = 0;
		size = ::fwrite(ptr, static_cast<int>(sizeof(char)), strlen(ptr),m_fil);
		::fclose(m_fil);
		m_fil = NULL;
		if(size>0)
		{
			return true;
		}else{
			return false;
		}
	}
	else{
		m_fil = NULL;
		return false;
	}
}

bool pyfree::writeListInfo(std::vector<std::string> list,const std::string path)
{
	size_t newSize = 0;
	FILE *new_m_fil=NULL;
	new_m_fil = ::fopen(path.c_str(),"a+");
	if(NULL!=new_m_fil)
	{
		for(size_t i=0,lSize=list.size(); i<lSize; i++)
		{
			newSize += ::fwrite(list.at(i).c_str(), static_cast<int>(sizeof(char)), strlen(list.at(i).c_str()),new_m_fil);
		}
		::fclose(new_m_fil);
	}
	new_m_fil = NULL;
	if(newSize>0){
		return true;
	}

	return false;
}

bool pyfree::readFromFile(char *ptr, int &size, int buf_size,const std::string& path, const std::string& mode)
{
	FILE *m_fil=NULL;
	m_fil = ::fopen(path.c_str(),mode.c_str());
	if(NULL!=m_fil)
	{
		size = static_cast<int>( ::fread(ptr, static_cast<int>(sizeof(char)), (size_t)buf_size,m_fil) );
		::fclose(m_fil);
		m_fil = NULL;
		if(size>0)
		{
			return true;
		}else
			return false;
	}else{
		m_fil = NULL;
		return false;
	}
}

//读取文件每一行得字符串,如果行中存在空格,划分该行字符串,并装在到容器中
bool pyfree::readListInfo(std::vector<std::vector<std::string> > &list,const std::string path,int codef)
{
	FILE *m_fil=NULL;
	m_fil = ::fopen(path.c_str(),"r");
	if(NULL!=m_fil)
	{
		char buf[1024] ={0};
		while(NULL!=::fgets(buf,1024,m_fil))
		{
			std::string _lineInfo = buf;
			trimEnd(_lineInfo);
			#ifdef __linux__
			switch (codef)
			{
				case 1:
				{
					char buff[1024]={0};
					g2u(buf,strlen(buf),buff,1024);
					_lineInfo = buff;
				}
					break;
				case 2:
				{
					char buff[1024]={0};
					a2u(buf,strlen(buf),buff,1024);
					_lineInfo = buff;
				}
					break;
				default:
					break;
			}
			#endif
			std::string buffer;// Have a buffer string
			std::stringstream _lineStr(_lineInfo);// Insert the string into a stream
			std::vector<std::string> _lineList;// Create vector to hold our words
			while(_lineStr >> buffer)
			{
				_lineList.push_back(buffer);
			}
			list.push_back(_lineList);
		}
		::fclose(m_fil);
		m_fil = NULL;
		if(list.empty()){
			return false;
		}
	}else{
		#ifdef WIN32
		Print_WARN("con't open %s, %d \n",path.c_str(), ::GetLastError());
		#endif
		#ifdef linux
		Print_WARN("con't open %s, %s \n",path.c_str(),strerror(errno));
		#endif
		m_fil = NULL;
		return false;
	}
	return true;
}

//将采用","间隔的字符串划分成子字符串集
void pyfree::getNumberFromStr(std::vector<std::string> &ids, std::string idsStr)
{
	if(""==idsStr||"NULL"==idsStr)
		return;
	std::string id = "";
	for(unsigned int i=0,idSize= static_cast<unsigned int>(idsStr.size()); i<idSize; i++)
	{
		if(','==idsStr[i])
		{//use str ',' to dirve the idsStr;
			if(""!=id)
			{
				ids.push_back(id);
				id.clear();
				id = "";
			}else{
				ids.push_back(id);
			}
		}else if(i==(idSize-1))
		{
			if(""!=id)
			{
				ids.push_back(id);
				id.clear();
				id = "";
			}
		}else{
			id.push_back(idsStr[i]);
		}
	}
}

//读取文件每一行得字符串,如果行中存在",",划分该行字符串,并装在到容器中
bool pyfree::readListInfo_dot(std::vector<std::vector<std::string> > &list,const std::string path,int codef)
{
	FILE *m_fil=NULL;
	m_fil = ::fopen(path.c_str(),"r");
	if(NULL!=m_fil)
	{
		char buf[1024] ={0};
		std::string _lineInfo = "";
		while(NULL!=::fgets(buf,1024,m_fil))
		{
			_lineInfo = buf;
			trim(_lineInfo);
			#ifdef __linux__
			switch (codef)
			{
				case 1:
				{
					char buff[1024]={0};
					g2u(buf,strlen(buf),buff,1024);
					_lineInfo = buff;
				}
					break;
				case 2:
				{
					char buff[1024]={0};
					a2u(buf,strlen(buf),buff,1024);
					_lineInfo = buff;
				}
					break;
				default:
					break;
			}
			#endif
			std::vector<std::string> _lineList;
			getNumberFromStr(_lineList,_lineInfo);
			list.push_back(_lineList);
		}
		::fclose(m_fil);
		m_fil = NULL;
		if(list.empty()){
			return false;
		}
	}else{
		#ifdef WIN32
		Print_WARN("con't open %s, %d \n",path.c_str(), ::GetLastError());
		#endif
		#ifdef linux
		Print_WARN("con't open %s, %s \n",path.c_str(),strerror(errno));
		#endif
		m_fil = NULL;
		return false;
	}
	return true;
}

//读取文件,并将每一行字符串载入容器
bool pyfree::readListInfo(std::vector<std::string> &list,const std::string path,int codef)
{
	FILE *m_fil=NULL;
	m_fil = ::fopen(path.c_str(),"r");
	if(NULL!=m_fil)
	{
		char buf[512] ={0};
		std::string _lineInfo="";
		while(NULL!=::fgets(buf,512,m_fil))
		{
			_lineInfo = buf;
			trimEnd(_lineInfo);
			#ifdef __linux__
			switch (codef)
			{
				case 1:
				{
					char buff[1024]={0};
					g2u(buf,strlen(buf),buff,1024);
					_lineInfo = buff;
				}
					break;
				case 2:
				{
					char buff[1024]={0};
					a2u(buf,strlen(buf),buff,1024);
					_lineInfo = buff;
				}
					break;
				default:
					break;
			}
			#endif
			list.push_back(_lineInfo);
		}
		::fclose(m_fil);
		m_fil = NULL;
		if(list.empty()){
			return false;
		}
	}else{
		#ifdef WIN32
		Print_WARN("con't open %s, %d \n",path.c_str(), ::GetLastError());
		#endif
		#ifdef linux
		Print_WARN("con't open %s, %s \n",path.c_str(),strerror(errno));
		#endif
		m_fil = NULL;
		return false;
	}
	return true;
}

//获得dire目录下扩展名为extName的所有文件名
void pyfree::getAllFileName_dot(const std::string& directory, const std::string& extName, std::vector<std::string>& fileNames)
{
	getAllFileNamePrivate(directory,extName,fileNames,true);
}

//获得dire目录下扩展名为extName的所有文件名
void pyfree::getAllFileName(const std::string& directory, const std::string& extName, std::vector<std::string>& fileNames)
{
	getAllFileNamePrivate(directory,extName,fileNames);
}

void pyfree::getAllFileNamePrivate(const std::string& directory, const std::string& extName, std::vector<std::string>& fileNames,bool f)
{
	#ifdef WIN32
	_finddata_t fileInfo;
	intptr_t hFile;
	std::string filter = directory;
	char bch = static_cast<char>(('//') & 0X00FF);
	if(filter[filter.size()-1] != bch)
	{
		filter.push_back(bch);
	}
	filter += "*.";
	filter += extName;
	hFile = _findfirst(filter.c_str(),&fileInfo);
	if(hFile == -1)
	{
		return;
	}
	do {
		if (extName.empty())
		{
			if ((fileInfo.attrib & _A_SUBDIR))
			{
				if (0==strcmp(fileInfo.name,".") || 0==strcmp(fileInfo.name,"..") )
				{
					continue;
				}
				fileNames.push_back(fileInfo.name);
			}
		}else{
			std::string name(fileInfo.name);
			if(f){
				fileNames.push_back(name);
			}else{
				fileNames.push_back(name.substr(0,name.find_last_of('.')));
			}
			// fileNames.push_back(name.substr(0,name.find_last_of('.')));
		}
	} while (_findnext(hFile,&fileInfo) == 0);
	_findclose(hFile);
	#endif

	#ifdef linux
	std::string curdir = directory;
	if(curdir[curdir.size()-1] != '/'){
		curdir.push_back('/');
	}
	DIR *dfd;
	if( (dfd = opendir(curdir.c_str())) == NULL )
	{
		Print_WARN("open %s error with msg is: %s\n",curdir.c_str(),strerror(errno));
        return;
	}
	struct dirent    *dp;
	while ((dp = readdir(dfd)) != NULL)
	{
		if (extName.empty()){
			if (dp->d_type == DT_DIR)
			{
				if ( 0==strcmp(dp->d_name, ".") || 0==strcmp(dp->d_name, "..") )
				{
					continue;
				}
				fileNames.push_back(dp->d_name);
			}
		}else{
			if ( NULL==strstr(dp->d_name, extName.c_str()) )
			{
				continue;
			}
			std::string name(dp->d_name);
			if(f)
			{
				fileNames.push_back(name);
			}else{
				fileNames.push_back(name.substr(0,name.find_last_of('.')));
			}
		}
	}
	if (NULL != dp) {
		delete dp;
		dp = NULL;
	}
	if (NULL != dfd) {
		closedir(dfd);
		dfd = NULL;
	}
	#endif
}

unsigned int pyfree::getFileModifyTime(const std::string file_path)
{
	unsigned int ret = 0;
#if defined(WIN32)
	_finddata_t fileInfo;
	intptr_t hFile;
	hFile = _findfirst(file_path.c_str(),&fileInfo);
	if(hFile != -1)
	{
		ret = static_cast<unsigned int>(fileInfo.time_write);
	}else{
		Print_WARN("get file %s last modify error: %d \n"
			,file_path.c_str(), ::GetLastError());
	}
	_findclose(hFile);
#elif defined(linux)
	struct stat el;
	if(0==stat(file_path.c_str(), &el))
	{
		ret =  static_cast<unsigned int>(el.st_mtime);
	}else{
		Print_WARN("get file %s last modify time error: %s\n"
			,file_path.c_str(),strerror(errno));
	}
#else
	ret = 0;
#endif // WIN32
	return ret;
}

void pyfree::renameFile(const std::string& _oldName, const std::string& _newName)
{
	#ifdef WIN32
	_finddata_t fileInfo;
	intptr_t hFile;
	hFile = _findfirst(_oldName.c_str(),&fileInfo);
	if(hFile == -1)
	{
		Print_WARN("can't find file %s \n",_oldName.c_str());
		writeToFile("",_newName,"w");
		return;
	}
	// do {
	// 	std::string name(fileInfo.name);
	// 	fileNames.push_back(name.substr(0,name.find_last_of('.')));
	// } while (_findnext(hFile,&fileInfo) == 0);
	_findclose(hFile);
	#endif
	#ifdef linux
	FILE* m_fil = ::fopen(_oldName.c_str(),"r");
	if(NULL==m_fil){
		return;
	}
	::fclose(m_fil);
	m_fil = NULL;
	#endif

	Print_NOTICE("%s, %s\n", _oldName.c_str(),_newName.c_str());
	int ret = rename(_oldName.c_str(),_newName.c_str());
	if(0 != ret)
	{
		Print_WARN("can't rename %s to %s \n",_oldName.c_str(),_newName.c_str());
		return;
	}
}

void pyfree::removeFile(const std::string& _Name)
{
	int ret = remove(_Name.c_str());
	if(0 != ret)
	{
		Print_WARN("can't remove %s \n",_Name.c_str());
		return;
	}
}

bool pyfree::isExist(std::string file)
{
	#ifdef WIN32
	_finddata_t fileInfo;
	intptr_t hFile = _findfirst(file.c_str(),&fileInfo);
	if(hFile == -1)
	{
		return false;
	}
	_findclose(hFile);

	return true;
	#else
	FILE *m_fil=NULL;
	m_fil=::fopen(file.c_str(),"rb");
	if(NULL==m_fil){
		return false;
	}else{
		::fclose(m_fil);
		m_fil = NULL;
	}
	return true;
	#endif
}

bool pyfree::isExist(std::string dir,std::string file)
{
	std::string path = dir;
#ifdef WIN32
	path+="\\";
#else
	path+="/";
#endif
	path+=file;
	return isExist(path);
};

void pyfree::divXmlFile(std::string _xmlFile,std::string _xmlDir,std::string _xmlDiv,bool utfFlag)
{
	static int substationIndex = 1;
	FILE *m_fil=NULL;
	FILE *new_m_fil=NULL;

	std::string _xmlNode="<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n";
	_xmlNode = utfFlag?ASCII2UTF_8(_xmlNode):_xmlNode;
	std::string _xmlHead = "<"+_xmlDiv;
	std::string _xmlEnd = "</"+_xmlDiv+">";
	if(NULL!=(m_fil=fopen(_xmlFile.c_str(),"rb")))
	{
		char buf[512] ={0};
		while(NULL!=::fgets(buf,512,m_fil))
		{
			std::string _lineInfo = buf;
			_lineInfo = utfFlag?ASCII2UTF_8(_lineInfo):_lineInfo;
			std::string::size_type _posH = _lineInfo.find(_xmlHead);
			if(std::string::npos != _posH)
			{
				char newxml[256]={0};
				sprintf(newxml,"%s\\%s_%d.xml",_xmlDir.c_str(),_xmlDiv.c_str(),substationIndex);
				if(NULL!=(new_m_fil=::fopen(newxml,"a+")))
				{
					int newSize = static_cast<int>(::fwrite(_xmlNode.c_str(), static_cast<int>(sizeof(char)), strlen(_xmlNode.c_str()),new_m_fil));
					if(newSize<=0)
					{
						Print_WARN("newxml=%s,newSize=%d write failed\n",newxml,newSize);
					}
				}else{
					Print_WARN("open %s error\n",newxml);
				}
			}
			if(NULL!=new_m_fil){
				int lineSize = static_cast<int>(::fwrite(_lineInfo.c_str(), static_cast<int>(sizeof(char)), strlen(_lineInfo.c_str()),new_m_fil));
				if(lineSize<=0){
					Print_WARN("write _lineInfo=%s, lineSize=%d error\n",_lineInfo.c_str(),lineSize);
				}
			}
			std::string::size_type  _posE = _lineInfo.find(_xmlEnd);
			if(std::string::npos != _posE)
			{
				if(NULL!=new_m_fil)
				{
					::fclose(new_m_fil);
					new_m_fil=NULL;
					substationIndex+=1;
				}
			}
		}
		::fclose(m_fil);
		m_fil=NULL;
	}else{
		Print_WARN("con't open %s \n",_xmlFile.c_str());
		m_fil = NULL;
	}
};

bool pyfree::createDir(std::string _dir)
{
	if(isExistDir(_dir))
		return true;
#ifdef WIN32
	int ret = _mkdir(_dir.c_str());
#else
	int ret = mkdir(_dir.c_str(), S_IRWXU | S_IRWXG | S_IRWXO);
#endif
	if (-1 == ret) {
#ifdef WIN32
		if (183 != GetLastError())
		{
			Print_WARN("create Directory %s is error,%d \r\n", _dir.c_str(), GetLastError());
			return false;
		}
#else
		if (EEXIST != errno) 
		{
			Print_WARN("create Directory %s is error, %s ! \r\n", _dir.c_str(), strerror(errno));
			return false;
		}else{
			Print_WARN("dir(%s) has exist,don't create it again!\n",_dir.c_str());
		}
#endif
	}
	return true;
};

bool pyfree::isExistDir(std::string _dir)
{
#ifdef WIN32
	if(!_access(_dir.c_str(),0))
	{
		return true;
	}
	else
	{
		// Print_WARN("%s is not exist!\n",_dir.c_str());
		return false;
	}
#else
	DIR *dfd;
	if( (dfd = opendir(_dir.c_str())) == NULL )
	{
        return false;
	}else{
		return true;
	}
#endif // WIN32
}

bool pyfree::getCurrentDir(char* dir_, int len_)
{
	char* ret=NULL;
	ret = getcwd(dir_, len_);
	return (NULL!=ret);
}

         strchange.cpp

#include "strchange.h"

#include <stdio.h>
#include <stdlib.h>
#ifdef __linux__
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <iconv.h>
#endif
#ifdef WIN32
#include <iostream>
#include <windows.h>
#endif
#include <vector>

#ifdef WIN32
//UTF-8 to Unicode
std::wstring pyfree::Utf82Unicode(const std::string& utf8string)
{
	int widesize = ::MultiByteToWideChar(CP_UTF8, 0, utf8string.c_str(), -1, NULL, 0);
	if (widesize == ERROR_NO_UNICODE_TRANSLATION)
	{
		throw std::exception("Invalid UTF-8 sequence.");
	}
	if (widesize == 0)
	{
		throw std::exception("Error in conversion.");
	}

	std::vector<wchar_t> resultstring(widesize);

	int convresult = ::MultiByteToWideChar(CP_UTF8, 0, utf8string.c_str(), -1, &resultstring[0], widesize);

	if (convresult != widesize)
	{
		throw std::exception("La falla!");
	}

	return std::wstring(&resultstring[0]);
};

//unicode to ascii

std::string pyfree::WideByte2Acsi(std::wstring& wstrcode)
{
	int asciisize = ::WideCharToMultiByte(CP_OEMCP, 0, wstrcode.c_str(), -1, NULL, 0, NULL, NULL);
	if (asciisize == ERROR_NO_UNICODE_TRANSLATION)
	{
		throw std::exception("Invalid UTF-8 sequence.");
	}
	if (asciisize == 0)
	{
		throw std::exception("Error in conversion.");
	}
	std::vector<char> resultstring(asciisize);
	int convresult =::WideCharToMultiByte(CP_OEMCP, 0, wstrcode.c_str(), -1, &resultstring[0], asciisize, NULL, NULL);

	if (convresult != asciisize)
	{
		throw std::exception("La falla!");
	}

	return std::string(&resultstring[0]);
};

///

//ascii to Unicode

std::wstring pyfree::Acsi2WideByte(std::string& strascii)
{
	int widesize = MultiByteToWideChar (CP_ACP, 0, (char*)strascii.c_str(), -1, NULL, 0);
	if (widesize == ERROR_NO_UNICODE_TRANSLATION)
	{
		throw std::exception("Invalid UTF-8 sequence.");
	}
	if (widesize == 0)
	{
		throw std::exception("Error in conversion.");
	}
	std::vector<wchar_t> resultstring(widesize);
	int convresult = MultiByteToWideChar (CP_ACP, 0, (char*)strascii.c_str(), -1, &resultstring[0], widesize);

	if (convresult != widesize)
	{
		throw std::exception("La falla!");
	}

	return std::wstring(&resultstring[0]);
};

//Unicode to Utf8

std::string pyfree::Unicode2Utf8(const std::wstring& widestring)
{
	int utf8size = ::WideCharToMultiByte(CP_UTF8, 0, widestring.c_str(), -1, NULL, 0, NULL, NULL);
	if (utf8size == 0)
	{
		throw std::exception("Error in conversion.");
	}

	std::vector<char> resultstring(utf8size);

	int convresult = ::WideCharToMultiByte(CP_UTF8, 0, widestring.c_str(), -1, &resultstring[0], utf8size, NULL, NULL);

	if (convresult != utf8size)
	{
		throw std::exception("La falla!");
	}

	return std::string(&resultstring[0]);
};

std::wstring pyfree::stringToWstring(const std::string& str)
{
    LPCSTR pszSrc = str.c_str();
    int nLen = MultiByteToWideChar(CP_ACP, 0, pszSrc, -1, NULL, 0);
    if (nLen == 0) 
        return std::wstring(L"");
 
    wchar_t* pwszDst = new wchar_t[nLen];
    if (!pwszDst) 
        return std::wstring(L"");
 
    MultiByteToWideChar(CP_ACP, 0, pszSrc, -1, pwszDst, nLen);
    std::wstring wstr(pwszDst);
    delete[] pwszDst;
    pwszDst = NULL;
 
    return wstr;
}

std::string pyfree::wstringToString(const std::wstring& wstr)
{
	LPCWSTR pwszSrc = wstr.c_str();
	int nLen = WideCharToMultiByte(CP_ACP, 0, pwszSrc, -1, NULL, 0, NULL, NULL);
	if (nLen == 0) 
		return std::string("");
	
	char* pszDst = new char[nLen];
	if (!pszDst) 
		return std::string("");
	
	WideCharToMultiByte(CP_ACP, 0, pwszSrc, -1, pszDst, nLen, NULL, NULL);
	std::string str(pszDst);
	delete[] pszDst;
	pszDst = NULL;
	
	return str;
}

#endif

#ifdef __linux__
//
int pyfree::code_convert(char *from_charset,char *to_charset,char *inbuf,size_t inlen,char *outbuf,size_t outlen)
{
    iconv_t cd;
    //int rc;
    char **pin = &inbuf;
    char **pout = &outbuf;

    cd = iconv_open(to_charset,from_charset);
    if (cd==0) return -1;
    memset(outbuf,0,outlen);
    if (-1==static_cast<int>(iconv(cd,pin,&inlen,pout,&outlen)))
	return -1;
    iconv_close(cd);
    return 0;
}
//
int pyfree::u2g(char *inbuf,int inlen,char *outbuf,int outlen)
{
	char _fbuf[32]="utf-8";
	char _tbuf[32]="gb2312";
    return code_convert(_fbuf,_tbuf,inbuf,inlen,outbuf,outlen);
}
//
int pyfree::g2u(char *inbuf,size_t inlen,char *outbuf,size_t outlen)
{
	char _fbuf[32]="gb2312";
	char _tbuf[32]="utf-8";
    return code_convert(_fbuf,_tbuf,inbuf,inlen,outbuf,outlen);
}

int pyfree::u2a(char *inbuf,int inlen,char *outbuf,int outlen)
{
	char _fbuf[32]="utf-8";
	char _tbuf[32]="ascii";
    return code_convert(_fbuf,_tbuf,inbuf,inlen,outbuf,outlen);
}

int pyfree::a2u(char *inbuf,int inlen,char *outbuf,int outlen)
{
	char _fbuf[32]="ascii";
	char _tbuf[32]="utf-8";
    return code_convert(_fbuf,_tbuf,inbuf,inlen,outbuf,outlen);
}

int pyfree::u2k(char *inbuf,int inlen,char *outbuf,int outlen)
{
	char _fbuf[32]="utf-8";
	char _tbuf[32]="gbk";
    return code_convert(_fbuf,_tbuf,inbuf,inlen,outbuf,outlen);
}

int pyfree::k2u(char *inbuf,int inlen,char *outbuf,int outlen)
{
	char _fbuf[32]="gbk";
	char _tbuf[32]="utf-8";
    return code_convert(_fbuf,_tbuf,inbuf,inlen,outbuf,outlen);
}

#endif

//utf-8 to ascii

std::string pyfree::UTF_82ASCII(std::string& strUtf8Code)
{
	#ifdef WIN32
	std::string strRet("");
	//
	std::wstring wstr = Utf82Unicode(strUtf8Code);
	//
	strRet = WideByte2Acsi(wstr);
	return strRet;
	#endif
	#ifdef __linux__
	char lpszBuf[1024]={0};
	u2k(const_cast<char*>(strUtf8Code.c_str()),strUtf8Code.size(),lpszBuf, 1024);
	return std::string(lpszBuf);
	#endif
};

//ascii to Utf8

std::string pyfree::ASCII2UTF_8(std::string& strAsciiCode)
{
	#ifdef WIN32
	std::string strRet("");
	//
	std::wstring wstr = Acsi2WideByte(strAsciiCode);
	//
	strRet = Unicode2Utf8(wstr);
	return strRet;
	#endif
	#ifdef __linux__
	char lpszBuf[1024]={0};
	k2u(const_cast<char*>(strAsciiCode.c_str()),strAsciiCode.size(),lpszBuf, 1024);
	return std::string(lpszBuf);
	#endif
};

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/333110.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【九宫格坐标排列 Objective-C语言】

一、这个案例做好之后的效果如图: 1.这个下载是可以点击的,当你点击之后,弹出一个框,过一会儿,框框自动消失,这里变成“已安装” 2.那么,我现在先问大家一句话:大家认为在这一个应用里面,它包含几个控件, 3个,哪3个:一个是图片框,一个是Label,一个是按钮, 这…

python学习笔记-查看数据结构、均值、中位数、分位数、众数、离中趋势(标准差、方差、求和、偏态系数、风险系数)正态分布pdf、cdf、ppf

①引入pandas包&#xff0c;命名为pd。 import pandas as pd ②读入HR.csv数据 dfpd.read_csv(“./data/HR.csv”) ③查看是什么结构 type(df) ④查看单个类别satisfaction_level的数据结构 type(df[“satisfaction_level”]) ⑤查看均值的数据结构 type(df.mean()) …

运行Whisper笔记(1)

最近chatGPT很火&#xff0c;就去逛了一下openai的github项目。发现了这个项目。 这个项目可以识别视频中的音频&#xff0c;转换出字幕。 带着一颗好奇的心就尝试自己去部署玩一玩 跟着这篇文章一步步来进行安装&#xff0c;并且跟着这篇文章解决途中遇到的问题。 途中还会遇…

男,26岁,做了一年多的自动化测试,最近在纠结要不要转行,求指点。?

最近一个粉丝在后台问我&#xff0c;啊大佬我现在26了&#xff0c;做了做了一年多的自动化测试&#xff0c;最近在纠结要不要转行&#xff0c;求指点。首选做IT这条路&#xff0c;就是很普通的技术蓝领。对于大部分来说干一辈子问题不大&#xff0c;但是发不了什么财。如果你在…

第015天:将APP发布到应用商店(完结)

应用已经开发出来了&#xff0c;下一步我们需要思考推广方面的工作。那么如何才能让更多的用户知 道并使用我们的应用程序呢&#xff1f;在手机领域&#xff0c;最常见的做法就是将程序发布到某个应用商店中&#xff0c;这 样用户就可以通过商店找到我们的应用程序&#xff0c;…

前端修行 - 与后端配合的那些事情

最近总结一下个人作为前端&#xff0c;与后端、测试、以及产品经理、UI设计之间配合的那些事情&#xff0c;想到哪里说到哪里 1 关于正确认识项目研发一号位都是后端的这个事情 项目研发一号位&#xff0c;在有的公司可能会叫做SDM&#xff08;software development manger&am…

springboot 接入websocket实现定时推送消息到客户端

目录说明代码实现说明 如标题&#xff0c;举例需求场景&#xff1a; 前端与后端websocket连接上后&#xff0c;多用户登录&#xff0c;后端根据不同用户定时发消息给前端用于展示 代码实现 1、 <dependency><groupId>org.springframework.boot</groupId>…

vit-pytorch实现 MobileViT注意力可视化

项目链接 https://github.com/lucidrains/vit-pytorch 注意一下参数设置&#xff1a; Parameters image_size: int. Image size. If you have rectangular images, make sure your image size is the maximum of the width and heightpatch_size: int. Number of patches. im…

git:详解git rebase命令

背景 今天无意中打开 git 官网&#xff0c;发现 git 命令还是很多的&#xff0c;然而我们常用的就那几个&#xff0c;今天来学习一个也不怎么常用的命令 rebase 官网链接 都说学一个东西最好的方式就是读他的 官方文档&#xff0c;这里我读了一遍&#xff0c;把一些核心的地…

读书思考:步步惊心的《技术陷阱》

《技术陷阱》这本书450页&#xff0c;43万字之巨&#xff0c;信息量密密麻麻&#xff0c;采集的资料极其丰富&#xff0c;复习了一遍大停滞、大分流、大平衡、大逆转时代&#xff0c;并展望未来。看完了有很多想法&#xff0c;随手写了下来&#xff0c;希望不是蹭热点。&#x…

vue 最详细教学篇(一)

文章目录前言前景Vue 的长期技术支持 (LTS)、终止支持 (EOL) 及其延长版服务学习vue 要掌握那些技能-为什么学习 vue走进vueHello World 起手提示&#xff1a;示例&#xff1a;示例解析编辑器 VSCodevsCode 插件正式使用 vue.js要使用 vue 就绕不开生命周期 下面是生命周期图&a…

全国青少年编程等级考试scratch一级真题2022年9月(含题库答题软件账号)

青少年编程等级考试scratch真题答题考试系统请点击电子学会-全国青少年编程等级考试真题Scratch一级&#xff08;2019年3月&#xff09;在线答题_程序猿下山的博客-CSDN博客_小航答题助手1点击绿旗&#xff0c;下列哪个选项可以实现播放马叫声并在声音全部播放完后&#xff0c;…

Java常见数据结构的排序与遍历(包括数组,List,Map)

数组遍历与排序 数组定义 //定义 int a[] new int[5]int[] a new int[5];//带初始值定义 int b[] {1,2,3,4,5};赋值 //定义时赋值 int b[] {1,2,3,4,5};//引用赋值 a[6] 1 a[9] 9 //未赋值为空取值 //通过下表取值&#xff0c;从0开始 b[1] 1 b[2] 2遍历 Test p…

C语言操作符详解 一针见血!

目录算数操作符移位操作符位操作符赋值操作符单目操作符关系操作符逻辑操作符条件操作符逗号表达式下标引用、函数调用和结构成员表达式求值11.1 隐式类型转换算数操作符&#x1f4ad; 注意/ 除法 --得到的是商% 取模&#xff08;取余&#xff09;--得到的是余数如果除法操作符…

CentOS 根路径下各个目录的作用及介绍

前言 很多小伙伴刚刚开始接触Linux系统时肯定和我一样&#xff0c;都很懵&#xff0c;黑黢黢的界面&#xff0c;一个个目录&#xff0c;没有图形化界面&#xff0c;看着难受&#xff0c;多接触了一些后会好受一些&#xff0c;不过&#xff0c;对各个目录的了解肯定也很基础&am…

若依框架---PageHelper分页(十)

在前几天的文章中&#xff0c;我们介绍了PageHelper的分页方法&#xff0c;研读代码定位到了ExecutorUtil.pageQuery(...)方法&#xff0c;并阅读到了其中的部分代码。 今天我们将看到重要的SQL修改代码。 getPageSql 我们接着看代码&#xff1a; if (!dialect.beforePage(…

2023爬虫学习笔记 -- 批量爬取图片

一、目标网址http://img.itlun.cn/uploads/allimg/180703/1-1PF3160531-lp.jpg二、右击图片获取图片地址http://img.itlun.cn/uploads/allimg/180703/1-1PF3160531-lp.jpg三、以二进制形式返回响应数据响应requests.get(网页,headers头) 响应内容响应.content四、存储二进制数据…

SpringBoot整合Mybatis的核心原理

0. 前言&#xff1a;1. 自动配置类MybatisAutoConfiguration&#xff1a;1.1. SqlSessionFactory的生成&#xff1a;1.2. Mapper的扫描和代理生成&#xff1a;1.2.1. MapperScannerConfigurer1.2.2. MapperFactoryBean1.2.3. getMapper生成代理对象2. 小结&#xff1a;0. 前言&…

Vue2仿网易云风格音乐播放器(附源码)

Vue2仿网易云风格音乐播放器1、整体效果2、使用技术3、实现内容4、源码5、使用图片1、整体效果 2、使用技术 使用了HTML5 CSS3进行页面布局及美化使用Vue2进行数据渲染与页面交互使用Axios发送http请求获取数据 3、实现内容 实现了搜索歌曲功能&#xff0c;输入歌手或歌曲关…

如果企业遭受到攻击应该进行怎样的处理

声明 本文是学习2018勒索病毒白皮书政企篇. 而整理的学习笔记,分享出来希望更多人受益,如果存在侵权请及时联系我们 政企遭遇勒索攻击分析 由于感染政企客户更有可能获得赎金&#xff0c;再加上勒索病毒本身也以服务器定向攻击为主&#xff0c;所以&#xff0c;2018年政企客…