Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

C#和C++ string类型含中文怎么序列化 #4482

Closed
Tgsgf opened this issue Apr 6, 2018 · 5 comments
Closed

C#和C++ string类型含中文怎么序列化 #4482

Tgsgf opened this issue Apr 6, 2018 · 5 comments
Labels

Comments

@Tgsgf
Copy link

Tgsgf commented Apr 6, 2018

C#和C++ 平台下string类型含中文序列化protobuf报错并出现乱码,怎么解决

@liujisi
Copy link
Contributor

liujisi commented Apr 6, 2018 via email

@xfxyjwf xfxyjwf closed this as completed Apr 6, 2018
@Tgsgf
Copy link
Author

Tgsgf commented Apr 10, 2018

@pherl
The problem has been solved. Thank you for your help.

@307509256
Copy link

@pherl
The problem has been solved. Thank you for your help.

how to solve?

@Tgsgf
Copy link
Author

Tgsgf commented Mar 4, 2019

@pherl
问题已经解决了。谢谢您的帮助。

怎么解决?

C++ must first convert strings to utf8 for serialization. The conversion is as follows:

#include <iostream>
#include <codecvt>

using namespace std;
#pragma comment(lib, "libprotobuf.lib")

const std::string ws2s(const wstring& ws)
{
	locale old_loc = locale::global(locale(""));
	const wchar_t* src_wstr = ws.c_str();
	size_t buffer_size = ws.size() * 4 + 1;
	char* dst_str = new char[buffer_size];
	memset(dst_str, 0, buffer_size);
	size_t i = 0;
	wcstombs_s(&i, dst_str, buffer_size, src_wstr, buffer_size);
	string result = dst_str;
	delete[]dst_str;
	locale::global(old_loc);
	return result;
}

const std::wstring s2ws(const string& s)
{
	locale old_loc = locale::global(locale(""));
	const char* src_str = s.c_str();
	const size_t buffer_size = s.size() + 1;
	wchar_t* dst_wstr = new wchar_t[buffer_size];
	wmemset(dst_wstr, 0, buffer_size);
	size_t i = 0;
	mbstowcs_s(&i, dst_wstr, buffer_size, src_str, buffer_size);
	wstring result = dst_wstr;
	delete[]dst_wstr;
	locale::global(old_loc);
	return result;
}

const std::string ws2utf8(const wstring& src)
{
	wstring_convert<codecvt_utf8<wchar_t>> conv;
	return conv.to_bytes(src);
}

const wstring utf8_2_ws(const string& src)
{
	wstring_convert<codecvt_utf8<wchar_t> > conv;
	return conv.from_bytes(src);
}

//////////////使用方法是先将字符串转成UTF-8
int main()
{
	TGS::MyInFo info;
	string name = "姓名:TGS";
	info.set_mingzi(ws2utf8(s2ws(name)));
	info.set_nianling(24);
	string dh = "123456789";
	info.set_dianhua(ws2utf8(s2ws(dh)));
	char a[400];
	memset(a, 0, sizeof(a));
	info.SerializeToArray(&a, sizeof(a));
	cout << a << endl;

	TGS::MyInFo tt;
	tt.ParseFromArray(a, sizeof(a));
	cout << ws2s(utf8_2_ws(tt.mingzi())) << " " << tt.nianling() << " " << ws2s(utf8_2_ws(tt.dianhua())) << endl;
	system("pause");
	return 0;
}

@VAllens
Copy link
Contributor

VAllens commented Dec 12, 2023

@pherl
问题已经解决了。谢谢您的帮助。

怎么解决?

C++ must first convert strings to utf8 for serialization. The conversion is as follows:

#include <iostream>
#include <codecvt>

using namespace std;
#pragma comment(lib, "libprotobuf.lib")

const std::string ws2s(const wstring& ws)
{
	locale old_loc = locale::global(locale(""));
	const wchar_t* src_wstr = ws.c_str();
	size_t buffer_size = ws.size() * 4 + 1;
	char* dst_str = new char[buffer_size];
	memset(dst_str, 0, buffer_size);
	size_t i = 0;
	wcstombs_s(&i, dst_str, buffer_size, src_wstr, buffer_size);
	string result = dst_str;
	delete[]dst_str;
	locale::global(old_loc);
	return result;
}

const std::wstring s2ws(const string& s)
{
	locale old_loc = locale::global(locale(""));
	const char* src_str = s.c_str();
	const size_t buffer_size = s.size() + 1;
	wchar_t* dst_wstr = new wchar_t[buffer_size];
	wmemset(dst_wstr, 0, buffer_size);
	size_t i = 0;
	mbstowcs_s(&i, dst_wstr, buffer_size, src_str, buffer_size);
	wstring result = dst_wstr;
	delete[]dst_wstr;
	locale::global(old_loc);
	return result;
}

const std::string ws2utf8(const wstring& src)
{
	wstring_convert<codecvt_utf8<wchar_t>> conv;
	return conv.to_bytes(src);
}

const wstring utf8_2_ws(const string& src)
{
	wstring_convert<codecvt_utf8<wchar_t> > conv;
	return conv.from_bytes(src);
}

//////////////使用方法是先将字符串转成UTF-8
int main()
{
	TGS::MyInFo info;
	string name = "姓名:TGS";
	info.set_mingzi(ws2utf8(s2ws(name)));
	info.set_nianling(24);
	string dh = "123456789";
	info.set_dianhua(ws2utf8(s2ws(dh)));
	char a[400];
	memset(a, 0, sizeof(a));
	info.SerializeToArray(&a, sizeof(a));
	cout << a << endl;

	TGS::MyInFo tt;
	tt.ParseFromArray(a, sizeof(a));
	cout << ws2s(utf8_2_ws(tt.mingzi())) << " " << tt.nianling() << " " << ws2s(utf8_2_ws(tt.dianhua())) << endl;
	system("pause");
	return 0;
}

It works for me and solves the cross language and cross platform encoding problem between my two programs.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

5 participants