utf8与ansi之间的转换

// file.cpp : Defines the entry point for the console application.
//
#include "stdafx.h"
#include <iostream>
#include <string>
#include <vector>
#include <fstream>
#include <windows.h>
#include <boost/filesystem.hpp>

namespace fs = boost::filesystem;

const int COUNT = 1024;
const std::string ret_success = "success";
const std::string ret_src_open = "error:源文件打开错误";
const std::string ret_dst_open = "error:目标文件打开错误";
const std::string ret_over_line = "error:文件中某行字符数过大";
const std::string ret_type_convert = "error:转换类型不正确";

typedef enum { UTF8_ANSI, ANSI_UTF8} TYPE_CONVERT; // 转换类型
std::string utf8_ansi(std::string utf8_path, std::string ansi_path); // UTF8转换为ANSI
std::string ansi_utf8(std::string ansi_path, std::string utf8_path); // ANSI转换为UTF8
int get_filenames(const std::string& dir, std::vector<std::string>& filenames); // 获取目录下的所有文件名
void code_convert(const std::string& src_dir,
				  const std::string& dst_dir,
				  TYPE_CONVERT type_convert,
				  std::string expanded_names = ".h.cpp.txt"); // 转换目录下所有指定扩展名的文件,路径用"//"

int _tmain(int argc, _TCHAR* argv[])
{
	
	system("pause");
	return 0;
}

std::string utf8_ansi(std::string utf8_path, std::string ansi_path)
{
	std::string ret = ret_success;
	std::fstream fsrc(utf8_path.c_str(), std::fstream::in);
	std::fstream fdst(ansi_path.c_str(), std::fstream::out | std::fstream::trunc);
	if (!fsrc.is_open())
	{
		return ret_src_open;
	}

	if (!fdst.is_open())
	{
		fsrc.close();
		return ret_dst_open;
	}

	std::string line;
	wchar_t wstr[COUNT];
	char src_path[COUNT<<1];
	bool is_first_line = true;
	while (!fsrc.eof())
	{
		std::getline(fsrc, line);
		//printf("0x%02x, 0x%02x", line[0], line[1]);
		if (line.size() >= (COUNT<<3)) // UTF8一个汉字需要用3个字节表示
		{
			ret = ret_over_line;
			break;
		}
		::ZeroMemory(wstr, sizeof(wstr));
		::ZeroMemory(src_path, sizeof(src_path));
		::MultiByteToWideChar(CP_UTF8, 0, line.c_str(), line.size(), wstr, COUNT);
		::WideCharToMultiByte(CP_ACP, 0, wstr, wcslen(wstr), src_path, COUNT<<1, 0, 0);
		int str_len = strlen(src_path);
		src_path[str_len] = '\n';
		if (is_first_line && (0x3F==src_path[0])) // 跳过第一行的第一个字符
		{
			fdst.write(src_path+1, str_len);
			is_first_line = false;
		}
		else
		{
			fdst.write(src_path, str_len+1);
		}
	}

	fsrc.close();
	fdst.close();
	return ret;
}

std::string ansi_utf8(std::string ansi_path, std::string utf8_path)
{
	std::string ret = ret_success;
	std::fstream fsrc(ansi_path.c_str(), std::fstream::in);
	std::fstream fdst(utf8_path.c_str(), std::fstream::out | std::fstream::trunc);
	if (!fsrc.is_open())
	{
		return ret_src_open;
	}

	if (!fdst.is_open())
	{
		fsrc.close();
		return ret_dst_open;
	}

	unsigned char head[3] = {0xEF, 0xBB, 0xBF};
	fdst.write((char*)head, 3); // UTF8文件头

	std::string line;
	wchar_t wstr[COUNT];
	char str[COUNT<<1];
	while (!fsrc.eof())
	{
		std::getline(fsrc, line);
		if (line.size() >= COUNT)
		{
			ret = ret_over_line;
			break;
		}

		::ZeroMemory(str, sizeof(str));
		::ZeroMemory(wstr, sizeof(wstr));
		::MultiByteToWideChar(CP_ACP, 0, line.c_str(), line.size(), wstr, COUNT);
		::WideCharToMultiByte(CP_UTF8, 0, wstr, wcslen(wstr), str, COUNT<<1, 0, 0);
		int len = strlen(str);
		str[len] = '\n';
		fdst.write(str, len+1);
	}

	fsrc.close();
	fdst.close();
	return ret;
}

int get_filenames(const std::string& dir, std::vector<std::string>& filenames)
{
	fs::path path(dir);
	if (!fs::exists(path))
	{
		return -1;
	}

	fs::directory_iterator end_iter;
	for (fs::directory_iterator iter(path); iter!=end_iter; ++iter)
	{
		if (fs::is_regular_file(iter->status()))
		{
			filenames.push_back(iter->path().string());
		}

		if (fs::is_directory(iter->status()))
		{
			get_filenames(iter->path().string(), filenames);
		}
	}

	return filenames.size();
}

void code_convert(const std::string& src_dir,
				  const std::string& dst_dir,
				  TYPE_CONVERT type_convert,
				  std::string expanded_names)
{
	int pos, first, second;
	std::string src_path;
	std::string src_right;
	std::string dst_path;
	std::vector<std::string> vs_expnames;
	std::vector<std::string> src_filenames;
	std::vector<std::string>::iterator iter1, iter2;

	if (UTF8_ANSI!=type_convert && ANSI_UTF8!=type_convert)
	{
		std::cout << ret_type_convert << std::endl;
		return;
	}

	if (get_filenames(src_dir, src_filenames) > 0)
	{
		// 获取所有扩展名
		while ((first = expanded_names.find('.')) != expanded_names.npos)
		{
			second = expanded_names.find('.', first+1);
			if (second != expanded_names.npos)
			{
				vs_expnames.push_back(expanded_names.substr(first, second-first));
				expanded_names = expanded_names.substr(second);
			}
			else
			{
				vs_expnames.push_back(expanded_names.substr(first));
				break;
			}
		}
		
		int num = 0;
		for (iter1=src_filenames.begin(); iter1!=src_filenames.end(); ++iter1)
		{
			// 获取目标文件路径
			src_path = (*iter1);
			pos = src_path.find(src_dir);
			src_right = src_path.substr(pos+src_dir.size(), src_path.size()-pos-src_dir.size());
			dst_path = dst_dir + src_right;

			// 转换指定扩展名文件
			for (iter2=vs_expnames.begin(); iter2!=vs_expnames.end(); ++iter2)
			{
				if (dst_path.substr(dst_path.size()-(*iter2).size()) == (*iter2))
				{
					std::cout << ++num << ": " << src_path << " => " << dst_path << std::endl;

					std::cout << ((UTF8_ANSI==type_convert) ?
						utf8_ansi(src_path, dst_path) :
						ansi_utf8(src_path, dst_path)) << std::endl;
					break;
				}
			}
		}
	}
}

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: 将UTF-8编码转换ANSI编码是一种常见的转换需求。UTF-8是一种变长编码方式,能够表示全球各种文字字符,而ANSI则是一种单字节编码,通常用于英语等西方语言。下面是一种将UTF-8转换ANSI的方法: 1. 首先,明确一点,UTF-8编码中的字符可能需要多个字节来表示,而ANSI编码只需要一个字节。因此,在转换过程中,如果UTF-8编码中的字符超出了ANSI编码范围,将无法直接进行转换。 2. 创建一个空字符串,用于存储转换后的ANSI编码。 3. 遍历UTF-8编码的每个字节: - 如果字节的最高位是0,表示该字节单独可以表示一个ANSI字符,直接将该字节添加到ANSI编码中。 - 如果字节的最高位是1,表示该字节与后续的字节一起组成一个UTF-8字符。读取后续的字节,构成完整的UTF-8字符。 - 判断UTF-8字符是否超出了ANSI编码范围。如果超出了,则不能进行转换。 - 如果没有超出ANSI编码范围,找到对应的ANSI字符,将其添加到ANSI编码中。 4. 返回转换后的ANSI编码。 需要注意的是,由于ANSI编码只能表示一部分字符,因此某些UTF-8字符可能无法转换为对应的ANSI字符。在实际转换时,可能需要根据具体的需求和使用环境进行处理和调整。 ### 回答2: C和UTF-8是不同的字符编码标准。C是一种早期的编程语言,它使用的是ANSI字符集作为默认的字符编码。ANSI字符集使用1个字节来表示一个字符,总共有256个字符,包括标点符号、数字和一些基本的拉丁字母。UTF-8是一种现代的字符编码标准,它是Unicode的一种实现方式,使用1到4个字节来表示一个字符,总共可以表示超过1百万个字符。 要将UTF-8编码的字符转换ANSI编码,需要注意的是ANSI字符集无法表示一些特殊的字符,因此一些不在ANSI字符集中的字符可能会丢失或替换为问号或其他无效字符。可以使用一些文本编辑软件或编程语言提供的转换函数来实现这个转换过程。 然而,需要注意的是,由于ANSI字符集的限制和UTF-8编码字符集的广泛使用,将UTF-8转换ANSI可能会导致信息的丢失或错误的表示,特别是对于包含非拉丁字母或特殊符号的文本。因此,更推荐使用支持UTF-8的字符编码,以保留原始文本的完整性和准确性。 ### 回答3: 将UTF-8编码转换ANSI编码需要使用特定的软件或工具。由于UTF-8编码包含了更多的字符和字符集,而ANSI编码只包含较少的字符集,所以转换时可能会有一些字符无法转换或出现乱码的情况。 首先,可以使用一些文本编辑器软件来进行这种转换。比如在Windows操作系统中,可以使用记事本打开UTF-8编码的文本文件,然后选择“另存为”选项,将编码格式选择为ANSI,然后保存即可。这样就将UTF-8编码转换为了ANSI编码。但需要注意的是,如果文本中包含某些特殊字符,转换后可能会出现乱码或字符丢失的情况。 另外,也可以使用一些第三方的编码转换工具来进行转换。这些工具可以将UTF-8编码的文本文件导入,然后选择转换ANSI编码,最后保存转换后的文件。这种方式相对来说更加灵活,可以对特定字符进行自定义的转换设置。 无论是使用文本编辑器还是编码转换工具,都需要注意转换后的结果可能不完全准确,特别是对于一些特殊字符和格式的处理。因此,在进行编码转换时,应该仔细检查转换后的文件,确保没有出现乱码或字符丢失的情况。对于一些重要的数据和文件,最好备份原始的UTF-8编码版本,以防止转换后无法还原的情况发生。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值