国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

使用 C++ 方式實現(xiàn) GBK 到 UTF-8 轉碼 (win / linux)

這篇具有很好參考價值的文章主要介紹了使用 C++ 方式實現(xiàn) GBK 到 UTF-8 轉碼 (win / linux)。希望對大家有所幫助。如果存在錯誤或未考慮完全的地方,請大家不吝賜教,您也可以點擊"舉報違法"按鈕提交疑問。

C++ 存在多種方式實現(xiàn) GBK 到 UTF-8 的轉碼

1 - 使用 Qt API


一般使用C++都會想到使用 Qt API QString 將 gbk 轉為 utf-8

std::string sgbk;
std::string sutf8 = QString::fromLocal8Bit(sgbk.data()).toUtf8().data());

此種方式,可以轉換 Windows 平臺運行時的 gbk 編碼的中文字符串為 utf-8 格式,linux 下需要使用 QTextCodec ,網(wǎng)上有很多,此處不做過多描述。
由于項目需要去掉 Qt 依賴,或者無法使用 Qt,所有給出以下兩種方法。

2 - 使用 std::codecvt


C++標準庫封裝了部分轉碼方法,需要通過 unicode 中轉,調用 <codecvt> 與 <clocale> 來實現(xiàn)。

首先實現(xiàn)四個基礎方法

class String {
private:
	static std::string UnicodeToUtf8(const std::wstring& wstr);
	static std::wstring Utf8ToUnicode(const std::string& str);
	static std::string UnicodeToAnsi(const std::wstring& wstr);
	static std::wstring AnsiToUnicode(const std::string& str);
};

unicode 與 utf-8 之間的相互轉換

std::string String::UnicodeToUtf8(const std::wstring& wstr)
{
	std::string out;
	try {
		std::wstring_convert<std::codecvt_utf8<wchar_t>> wcv;
		out = wcv.to_bytes(wstr);
	}
	catch (const std::exception & e)
	{
		std::cerr << e.what() << std::endl;
	}
	return out;
}

std::wstring String::Utf8ToUnicode(const std::string& str)
{
	std::wstring ret;
	try
	{
		std::wstring_convert<std::codecvt_utf8<wchar_t>> wcv;
		ret = wcv.from_bytes(str);
	}
	catch (const std::exception & e)
	{
		std::cerr << e.what() << std::endl;
	}
	return ret;
}

然后實現(xiàn) unicode 與 ansi 之間的轉換

std::string String::UnicodeToAnsi(const std::wstring& wstr)
{
	std::string ret;
	std::mbstate_t state{};
	const wchar_t* src = wstr.data();
	size_t len = std::wcsrtombs(nullptr, &src, 0, &state);

	if (len != static_cast<size_t>(-1))
	{
		std::unique_ptr<char[]> buff(new char[len + 1]);
		len = std::wcsrtombs(buff.get(), &src, len, &state);
		if (len != static_cast<size_t>(-1))
		{
			ret.assign(buff.get(), len);
		}
	}
	return ret;
}

std::wstring String::AnsiToUnicode(const std::string& str)
{
	std::wstring ret;
	std::mbstate_t state{};
	const char* src = str.data();
	size_t len = std::mbsrtowcs(nullptr, &src, 0, &state);
	if (len != static_cast<size_t>(-1))
	{
		std::unique_ptr<wchar_t[]> buff(new wchar_t[len + 1]);
		len = std::mbsrtowcs(buff.get(), &src, len, &state);
		if (len != static_cast<size_t>(-1))
		{
			ret.assign(buff.get(), len);
		}
	}
	return ret;
}

然后實現(xiàn)最外層的方法

class String {
public:
	static std::string Utf8ToAnsi(const std::string& str);
	static std::string AnsiToUtf8(const std::string& str);
};

只需要級聯(lián)調用即可

std::string String::Utf8ToAnsi(const std::string& str)
{
	return UnicodeToAnsi(Utf8ToUnicode(str));
}

std::string String::AnsiToUtf8(const std::string& str)
{
	return UnicodeToUtf8(AnsiToUnicode(str));
}

主函數(shù)入口處需設置 setlocale,此處調用為了使 ANSI 編碼生效,由于 ANSI 在不同平臺下表示的編碼不同。

// to let ANSI take effects to enable AnsiToUtf8
setlocale(LC_CTYPE, "");

完整代碼 String.h,實現(xiàn)一個純接口類

#pragma once
#include <string>
class String
{
public:
	// 對外接口
	static std::string Utf8ToAnsi(const std::string& str);
	static std::string AnsiToUtf8(const std::string& str);

private:
	// 內部調用
	static std::string UnicodeToUtf8(const std::wstring& wstr);
	static std::wstring Utf8ToUnicode(const std::string& str);
	static std::string UnicodeToAnsi(const std::wstring& wstr);
	static std::wstring AnsiToUnicode(const std::string& str);
	
	// disabled functions
	String() = delete;
	~String() = delete;
	String(const String& rhs) = delete;
	String& operator=(const String& rhs) = delete;
};

#pragma once 現(xiàn)在較新版本的編譯器一般都支持,如果不支持需要換成
#ifndef __STRING_H__
#define __STRING_H__
#endif // __STRING_H__
防止頭文件重復包含

String.cpp

#include "String.h"
#include <codecvt>
#include <iostream>

std::string String::Utf8ToAnsi(const std::string& str)
{
	return UnicodeToAnsi(Utf8ToUnicode(str));
}

std::string String::AnsiToUtf8(const std::string& str)
{
	return UnicodeToUtf8(AnsiToUnicode(str));
}

std::string String::UnicodeToUtf8(const std::wstring& wstr)
{
	std::string out;
	try {
		std::wstring_convert<std::codecvt_utf8<wchar_t>> wcv;
		out = wcv.to_bytes(wstr);
	}
	catch (const std::exception & e)
	{
		std::cerr << e.what() << std::endl;
	}
	return out;
}

std::wstring String::Utf8ToUnicode(const std::string& str)
{
	std::wstring ret;
	try
	{
		std::wstring_convert<std::codecvt_utf8<wchar_t>> wcv;
		ret = wcv.from_bytes(str);
	}
	catch (const std::exception & e)
	{
		std::cerr << e.what() << std::endl;
	}
	return ret;
}

std::string String::UnicodeToAnsi(const std::wstring& wstr)
{
	std::string ret;
	std::mbstate_t state{};
	const wchar_t* src = wstr.data();
	size_t len = std::wcsrtombs(nullptr, &src, 0, &state);

	if (len != static_cast<size_t>(-1))
	{
		std::unique_ptr<char[]> buff(new char[len + 1]);
		len = std::wcsrtombs(buff.get(), &src, len, &state);
		if (len != static_cast<size_t>(-1))
		{
			ret.assign(buff.get(), len);
		}
	}
	return ret;
}

std::wstring String::AnsiToUnicode(const std::string& str)
{
	std::wstring ret;
	std::mbstate_t state{};
	const char* src = str.data();
	size_t len = std::mbsrtowcs(nullptr, &src, 0, &state);
	if (len != static_cast<size_t>(-1))
	{
		std::unique_ptr<wchar_t[]> buff(new wchar_t[len + 1]);
		len = std::mbsrtowcs(buff.get(), &src, len, &state);
		if (len != static_cast<size_t>(-1))
		{
			ret.assign(buff.get(), len);
		}
	}
	return ret;
}

由于 setlocale 會影響全局,也就是所有的 lib 庫都會影響,有可能會出現(xiàn)問題,所以建議第三種方法。

3 - 使用 WinAPI 和 iconv


Windows 平臺使用 Win API, linux 平臺使用 iconv 庫

首先實現(xiàn)一個 linux 下的通用函數(shù),由于直接使用 std::string 和 iconv 接口會出現(xiàn)轉換失敗的問題。

// 根據(jù)不同的平臺包含不同的頭文件
#if defined(_WIN32) || defined(_MSC_VER) || defined(WIN64) 
#include <Windows.h>
#elif defined(__linux__) || defined(__GNUC__)
#include <iconv.h>
#endif

#if defined(__linux__) || defined(__GNUC__)
int EncodingConvert(const char* charsetSrc, const char* charsetDest, char* inbuf,
	size_t inSz, char* outbuf, size_t outSz)
{
	iconv_t cd;
	char** pin = &inbuf;
	char** pout = &outbuf;
	cd = iconv_open(charsetDest, charsetSrc);
	if (0 == cd)
	{
		std::cerr << charsetSrc << " to " << charsetDest 
		<< " conversion not available" << std::endl; 
		return -1;
	}

	if (-1 == static_cast<int>(iconv(cd, pin, &inSz, pout, &outSz)))
	{
		std::cerr << "conversion failure" << std::endl;
		return -1;
	}

	iconv_close(cd);
	**pout = '\0';
	return 0;
}
#endif

實現(xiàn) GBK 轉 UTF-8 的接口,設置轉換失敗和非 Windows 和非 Linux 系統(tǒng),返回原字符串。

std::string GbkToUtf8(const std::string& str)
{
#if defined(_WIN32) || defined(_MSC_VER) || defined(WIN64)
	int len = MultiByteToWideChar(CP_ACP, 0, str.c_str(), -1, NULL, 0);
	wchar_t* wstr = new wchar_t[len + 1ull];
	memset(wstr, 0, len + 1ull);
	MultiByteToWideChar(CP_ACP, 0, str.c_str(), -1, wstr, len);
	len = WideCharToMultiByte(CP_UTF8, 0, wstr, -1, NULL, 0, NULL, NULL);
	char* cstr = new char[len + 1ull];
	memset(cstr, 0, len + 1ull);
	WideCharToMultiByte(CP_UTF8, 0, wstr, -1, cstr, len, NULL, NULL);
	std::string res(cstr);

	if (wstr) delete[] wstr;
	if (cstr) delete[] cstr;

	return res;
#elif defined(__linux__) || defined(__GNUC__)
	size_t len = str.size() * 2 + 1;
	char* temp = new char[len];
	if (EncodingConvert("gb2312", "utf-8", const_cast<char*>(str.c_str()), str.size(), temp, len)
		> = 0)
	{
		std::string res;
		res.append(temp);
		delete[] temp;
		return res;
	}
	else
	{
		delete[]temp;
		return str;
	}
#else
	std::cerr << "Unhandled operating system." << std::endl;
	return str;
#endif
}

實現(xiàn) UTF-8 轉 GBK 的接口,與前者一樣,非 Windows 和非 Linux 系統(tǒng)未處理和處理失敗返回原字符串

std::string Utf8ToGbk(const std::string& str)
{
#if defined(_WIN32) || defined(_MSC_VER) || defined(WIN64) 
    // calculate length
	int len = MultiByteToWideChar(CP_UTF8, 0, str.c_str(), -1, NULL, 0);
	wchar_t* wsGbk = new wchar_t[len + 1ull];
	// set to '\0'
	memset(wsGbk, 0, len + 1ull);
	MultiByteToWideChar(CP_UTF8, 0, str.c_str(), -1, wsGbk, len);
	len = WideCharToMultiByte(CP_ACP, 0, wsGbk, -1, NULL, 0, NULL, NULL);
	char* csGbk = new char[len + 1ull];
	memset(csGbk, 0, len + 1ull);
	WideCharToMultiByte(CP_ACP, 0, wsGbk, -1, csGbk, len, NULL, NULL);
	std::string res(csGbk);

	if (wsGbk)
	{
	 	delete[] wsGbk;
	}
	
	if (csGbk)
	{
		delete[] csGbk;
	}

	return res;
#elif defined(__linux__) || defined(__GNUC__)
	size_t len = str.size() * 2 + 1;
	char* temp = new char[len];
	if (EncodingConvert("utf-8", "gb2312", const_cast<char*>(str.c_str()),
		str.size(), temp, len) >= 0)
	{
		std::string res;
		res.append(temp);
		delete[] temp;
		return res;
	}
	else
	{
		delete[] temp;
		return str;
	}

#else
	std::cerr << "Unhandled operating system." << std::endl;
	return str;
#endif
}

GBK 轉 UTF-8 兩個平臺均驗證測試可行。文章來源地址http://www.zghlxwxcb.cn/news/detail-698688.html

到了這里,關于使用 C++ 方式實現(xiàn) GBK 到 UTF-8 轉碼 (win / linux)的文章就介紹完了。如果您還想了解更多內容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來自互聯(lián)網(wǎng)用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。如若轉載,請注明出處: 如若內容造成侵權/違法違規(guī)/事實不符,請點擊違法舉報進行投訴反饋,一經查實,立即刪除!

領支付寶紅包贊助服務器費用

相關文章

  • 織夢GBK/GB2312轉utf-8編碼操作步驟(全站修改方法)

    目前MIP對編碼是有嚴格要求,必須是UTF-8,那么對于大部分GBK或者GB2312的用戶只能先將網(wǎng)站整體進行編碼轉換,才能進行MIP改造,不然改造后的頁面是亂碼一大片。 為什么MIP只支持utf-8?目前部分手機自帶瀏覽器僅支持UTF-8,打開GBK的網(wǎng)站會出現(xiàn)亂碼,所以為了手機的兼容性,

    2023年04月24日
    瀏覽(39)
  • python,Pandas讀取csv文件gbk編碼和utf-8編碼都報錯

    python,Pandas讀取csv文件gbk編碼和utf-8編碼都報錯

    用Pandas讀取csv文件,read_csv(),使用默認的 encoding = ‘utf-8’ 和 encoding = ‘gbk’ 都報錯,如下圖。最終通過 統(tǒng)一編碼方式 解決了,操作很簡單,但是問題解決的探索過程并不是特別順利,所以記錄一下,給朋友們參考~ 統(tǒng)一編碼方式,將csv文件的編碼格式改為utf-8。 具體操作

    2024年01月16日
    瀏覽(93)
  • UTF-8、UTF-16、Unicode、GB2312、GBK、GB18030一次說清楚

    1、關于存儲編碼和顯示編碼的區(qū)別。 Unicode是顯示編碼,UTF-8、UTF-16、GB2312、GBK、GB18030都是存儲/傳輸方面使用,也叫做存儲編碼、處理編碼,你在計算機上看見的所有文字都從存儲編碼轉成顯示編碼后,顯示出來,當你單機保存時又從顯示編碼轉換為存儲編碼存儲起來。 2、

    2024年02月12日
    瀏覽(17)
  • UTF-8、GB2312、GBK、GB18030、ISO-8859-1(也稱Latin-1):兼容ASCII編碼

    ASCII碼是單字節(jié)的,首位為0,后面表示的值就是Unicode碼點,范圍為0x00-0x7F,共表示128個字符。 UTF-8和ASCII兼容 :因為對于單字節(jié)的符號,UTF-8 編碼和 ASCII 碼是相同的, 所以 UTF-8 能兼容 ASCII 編碼。 GB2312和ASCII兼容 :對于ASCII范圍以內的字符,GB2312編碼的機內碼(不是區(qū)位碼)

    2024年02月16日
    瀏覽(18)
  • 【錯誤記錄】IntelliJ IDEA 中編譯運行報錯 ( 當前設置 GBK 編碼 | 錯誤: 編碼UTF-8的不可映射字?? )

    【錯誤記錄】IntelliJ IDEA 中編譯運行報錯 ( 當前設置 GBK 編碼 | 錯誤: 編碼UTF-8的不可映射字?? )

    當前的 IntelliJ IDEA 設置的編碼為 GBK 編碼 , 選擇 \\\" 菜單欄 / File / Settings \\\" 選項 , 在 \\\" File Encodings \\\" 中 , 查看 工程的編碼 , 運行時報錯 : 在中文注釋的位置 , 編碼報錯 ; D:\\002_Project\\003_Java_WorkExsamplesrcmainjavaArrowCanvas.java:17 : 錯誤: 編碼UTF-8的不可映射字?? // ??????? ^

    2024年02月14日
    瀏覽(34)
  • 使用sublime發(fā)現(xiàn)沒有gbk編碼

    使用sublime發(fā)現(xiàn)沒有gbk編碼

    默認情況下,我們的 Sublime是沒有 GBK編碼格式設置了,為了我們的文件設置為 GBK,應當安裝 GBK選項插件。 安裝ConvertToUTF8插件 ①首選項--package control--Install Package ②彈出新的輸入框輸入:ConvertToUTF8,會出現(xiàn)ConvertToUTF8選項,選中安裝即可。 ③安裝成功后,重啟sublime ④比較一

    2024年02月16日
    瀏覽(33)
  • JavaScript實現(xiàn)字符編碼轉換utf-8/gbk(附完整源碼)

    以上代碼中,我們使用了JavaScript內置的TextEncoder和TextDecoder類來實現(xiàn)字符編碼轉換。這兩個類是ES6新增的特性,需要在支持ES6的瀏覽器上才能正常運行。 使用示例: 運行結果說明轉換成功。需要注意的是,在不同的瀏覽器中,對字符編碼的支持程度可能不同,因此在使用時需

    2024年02月04日
    瀏覽(53)
  • linux修改locale字符集編碼為UTF-8/GBK,修改語言區(qū)域為zh-CN(中文-中國)

    linux系統(tǒng)的語言、區(qū)域、字符集編碼由`locale’ [lo??k?l] 決定。 對應配置文件路徑: centos7 /etc/locale.conf centos6 /etc/sysconfig/i18n 以下以centos&為例 LANG= LC_CTYPE=“POSIX” LC_NUMERIC=“POSIX” LC_TIME=“POSIX” LC_COLLATE=“POSIX” LC_MONETARY=“POSIX” LC_MESSAGES=“POSIX” LC_PAPER=“POSIX” LC_NAME=“

    2024年02月13日
    瀏覽(23)
  • dedecms編碼轉換方法 gbk轉UTF-8,UTF-8轉GBK(推薦)

    經常遇到編碼轉換的問題,有的是購買了模板但是模板編碼與程序編碼不符,導致出現(xiàn)亂碼.今天小編給大家分享一篇教程幫助大家解決如何轉換模板文件的編碼和程序的編碼問題,一起看看吧! 1.如何轉換模板文件編碼? 首先下載一個編碼轉換軟件 51EC模板轉碼專用工具v1.0免費

    2024年02月03日
    瀏覽(20)
  • idea打的包字符集為GBK

    idea打的包字符集為GBK

    1.最近對接一個打印機廠家的機器,他們對與打印數(shù)據(jù)要求字符集是UTF-8的,做完程序在自己idea上運行是是能夠打印的,但是打包后,就不能夠打印了。然后問了設備方是否是他們機器的原因,后面他們問了我這報錯碼,他們對照文檔,說是打印的參數(shù)有問題,然后問我是不

    2024年02月11日
    瀏覽(18)

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請作者喝杯咖啡吧~博客贊助

支付寶掃一掃領取紅包,優(yōu)惠每天領

二維碼1

領取紅包

二維碼2

領紅包