C++ CSV 中文 乱码 UTF-8 ANSI

要正确读取包含中文字符的CSV文件,需要确保文件是以UTF-8编码保存的,并且在读取文件时正确处理编码。使用 std::wifstream 并设置其字节流的编码方式可以解决乱码问题。以下是修改后的代码:

代码说明:

  1. 设置UTF-8编码

    • 使用 std::localestd::codecvt_utf8<wchar_t> 设置文件流为UTF-8编码。这确保了在读取包含中文字符的文件时,字符能够正确解码。
  2. 读取CSV文件

    • 读取文件的每一行,并将其分割成键和值。
    • 将键字符串转换为 long 型,并将键值对存储在 g_TextCode 中。
  3. 错误处理

    • 在转换键字符串时,如果发生 std::invalid_argumentstd::out_of_range 异常,记录错误并继续处理下一行。
#include <unordered_map>
#include <string>
#include <fstream>
#include <sstream>
#include <iostream>
#include <locale>
#include <codecvt>

static const std::wstring TextCodeDataName = L"code.csv";
std::unordered_map<long, std::wstring> g_TextCode;
static bool isTextInit = false;

bool Init()
{
	std::wstring binpathstr{L"e:/" };
	binpathstr += TextCodeDataName;

	std::wifstream file(binpathstr);
	if (!file.is_open()) {
		std::wcerr << L"无法打开文件: " << binpathstr << std::endl;
		return false;
	}

	// 设置文件流使用UTF-8编码
	file.imbue(std::locale(file.getloc(), new std::codecvt_utf8<wchar_t>));

	std::wstring line;
	while (std::getline(file, line)) {
		std::wstringstream linestream(line);
		std::wstring keyStr, value;
		if (std::getline(linestream, keyStr, L',') && std::getline(linestream, value)) {
			try {
				long key = std::stol(keyStr);
				g_TextCode[key] = value;
			}
			catch (const std::invalid_argument&) {
				std::wcerr << L"CSV文件中无效的键: " << keyStr << std::endl;
				continue;
			}
			catch (const std::out_of_range&) {
				std::wcerr << L"CSV文件中超出范围的键: " << keyStr << std::endl;
				continue;
			}
		}
	}

	file.close();
	isTextInit = true;
	return isTextInit;
}

这种方法确保了从UTF-8编码的CSV文件中读取中文字符时不会出现乱码问题。如果文件已经是UTF-8编码的,这段代码应该能正确读取并处理文件内容。

添加一个辅助函数用于ANSI到宽字符(wchar_t)的转换:

std::wstring AnsiToWString(const std::string& str)
{
    int len;
    int slength = static_cast<int>(str.length()) + 1;
    len = MultiByteToWideChar(CP_ACP, 0, str.c_str(), slength, 0, 0);
    std::wstring wstr(len, L'\0');
    MultiByteToWideChar(CP_ACP, 0, str.c_str(), slength, &wstr[0], len);
    return wstr;
}
    std::string line;
    while (std::getline(file, line)) {
        std::wstring wline = AnsiToWString(line);
        std::wstringstream linestream(wline);
        std::wstring keyStr, value;
        if (std::getline(linestream, keyStr, L',') && std::getline(linestream, value)) {
            try {
                long key = std::stol(keyStr);
                g_TextCode[key] = value;
            }
            catch (const std::invalid_argument&) {
                std::wcerr << L"CSV文件中无效的键: " << keyStr << std::endl;
                continue;
            }
            catch (const std::out_of_range&) {
                std::wcerr << L"CSV文件中超出范围的键: " << keyStr << std::endl;
                continue;
            }
        }
    }

相关推荐

  1. C++ CSV 中文 UTF-8 ANSI

    2024-06-11 15:00:04       8 阅读
  2. Android 写入 csv ,设置UTF-8的流也不行

    2024-06-11 15:00:04       44 阅读
  3. CentOS 中文

    2024-06-11 15:00:04       24 阅读

最近更新

  1. TCP协议是安全的吗?

    2024-06-11 15:00:04       18 阅读
  2. 阿里云服务器执行yum,一直下载docker-ce-stable失败

    2024-06-11 15:00:04       19 阅读
  3. 【Python教程】压缩PDF文件大小

    2024-06-11 15:00:04       19 阅读
  4. 通过文章id递归查询所有评论(xml)

    2024-06-11 15:00:04       20 阅读

热门阅读

  1. 微信小程序轮播

    2024-06-11 15:00:04       6 阅读
  2. 数据仓库技术及应用(Hive函数)

    2024-06-11 15:00:04       9 阅读
  3. 数据结构:顺序表

    2024-06-11 15:00:04       8 阅读
  4. 排序算法案例

    2024-06-11 15:00:04       9 阅读
  5. Vue基础面试题(一)

    2024-06-11 15:00:04       7 阅读
  6. spring

    spring

    2024-06-11 15:00:04      8 阅读
  7. Web前端开发学习资料:深度探索与开发实践

    2024-06-11 15:00:04       8 阅读
  8. Golang 避坑指南

    2024-06-11 15:00:04       7 阅读