环境VS2017 unicode字符集
MFC操作ini文件方法
struct Mypara
{
std::string type;
int ivalue;
double dvalue;
std::string str;
Mypara(int ivalue) :ivalue(ivalue) {
type = "int";
}
Mypara(double dvalue) :dvalue(dvalue) {
type = "double";
}
Mypara(std::string str) :str(str) {
type = "string";
}
};
std::map<std::string, std::string> m_parameterAnnotates;//参数注释
std::map<std::string, Mypara> m_parametersInit; //初始化参数
std::map<std::string, Mypara> m_parameters; //参数map
CString m_paraFileName{"../config/cfg.ini"};//参数文件
wchar_t* Utf8_2_Unicode(char* row_i);
std::string UTF8ToGB(const char* str); //读取中文的需要的转换
bool loadParam();
bool MyWritePrivateProfileString(CString cs1, CString cs2, CString value, CString paraFileName);//在unicode环境中直接调用WritePrivateProfileString使用的是WritePrivateProfileStringW写入的将是乱码
bool reWriteParam();
wchar_t* Utf8_2_Unicode(char* row_i)
{
int len = MultiByteToWideChar(CP_UTF8, 0, row_i, strlen(row_i), NULL, 0);
wchar_t *wszStr = new wchar_t[len + 1];
MultiByteToWideChar(CP_UTF8, 0, row_i, strlen(row_i), wszStr, len);
wszStr[len] = '\0';
return wszStr;
}
std::string UTF8ToGB(const char* str)
{
std::string result;
WCHAR *strSrc;
LPSTR szRes;
//获得临时变量的大小
int i = MultiByteToWideChar(CP_UTF8, 0, str, -1, NULL, 0);
strSrc = new WCHAR[i + 1];
MultiByteToWideChar(CP_UTF8, 0, str, -1, strSrc, i);
//获得临时变量的大小
i = WideCharToMultiByte(CP_ACP, 0, strSrc, -1, NULL, 0, NULL, NULL);
szRes = new CHAR[i + 1];
WideCharToMultiByte(CP_ACP, 0, strSrc, -1, szRes, i, NULL, NULL);
result = szRes;
delete[]strSrc;
delete[]szRes;
return result;
}
bool loadParam()
{
//std::string fileName = "../config/cfg.ini";
std::string fileName = (CW2A)m_paraFileName;
std::ifstream in(fileName, std::ios_base::in | std::ios_base::binary);//读取输入流,待了解读取方式:只读和以二进制文件方式读取
std::string line, preAnnotate, name, value;
std::string::size_type pos;
int index = 1;
try {
if (in) {
std::getline(in, preAnnotate);
preAnnotate = UTF8ToGB(preAnnotate.c_str()).c_str();
while (!in.eof()) {
++index;
std::getline(in, line);
if (strcmp(line.c_str(), "") != 0) {
line = UTF8ToGB(line.c_str()).c_str();
if (isalnum(line[0])) {//如果是数字或者字母则判断为参数
pos = line.find("=");
if (pos != std::string::npos)//找到
{
name = line.substr(0, pos);
if (m_parameters.find(name) != m_parameters.end()) {
CString CWrongStr;
CWrongStr.Format(_T("%s%d"), _T("存在相同的键!行号:"), index);
MessageBox(CWrongStr);
return FALSE;
}
value = line.substr(pos + 1, line.length() - pos - 2);//注意去除回车
pos = value.find("\"");//注意单个引号时和两个引号时引发的异常
if (pos != std::string::npos)//找到
{
if (value[0] == '\"'&&value[value.length() - 1] == '\"')//找到
{
value = value.substr(1, value.length() - 2);
Mypara p(value);
//p.type = "string";
//p.str = value;
//m_parameters[name] = p;
m_parameters.insert(make_pair(name, p));
m_parameterAnnotates[name] = preAnnotate;
}
else {
CString CWrongStr;
CWrongStr.Format(_T("%s%d%s"), _T("参数非法\"号错误警告!行号:"), index, _T("检查中英文"));
MessageBox(CWrongStr);
}
}
else {
pos = value.find(".");//注意单个引号时和两个引号时引发的异常
if (pos != std::string::npos)//找到
{
Mypara p(std::stod(value));
//p.type = "double";
//p.dvalue = std::stod(value);
//m_parameters[name] = p;
m_parameters.insert(make_pair(name, p));
m_parameterAnnotates[name] = preAnnotate;
}
else {
Mypara p(std::stoi(value));
//p.type = "int";
//p.ivalue = std::stoi(value);
//m_parameters[name] = p;
m_parameters.insert({ name, p });
//m_parameters.insert(make_pair(name, p));
m_parameterAnnotates[name] = preAnnotate;
}
}
}
else {
CString CWrongStr;
CWrongStr.Format(_T("%s%d%s"), _T("参数非法没有=号警告!行号:"), index, _T("检查中英文"));
MessageBox(CWrongStr);
}
}
}
preAnnotate = line;
}
in.close();
}
else {
return FALSE;
}
}
catch (...) {
CString CWrongStr;
CWrongStr.Format(_T("%s%d"), _T("文件读取失败!行号:"), index);
MessageBox(CWrongStr);
in.close();
return FALSE;
}
//写入测试
{
CString value;
double nSelD = 523.4;
value.Format(_T("%lf"), nSelD + 1);
WritePrivateProfileString(TEXT("connom"), TEXT("connom_num"), value, m_paraFileName);
m_parameters.at("connom_num").dvalue = nSelD;
value = "\"";
value += "your_stringaaaa";
value += "\"";
WritePrivateProfileString(TEXT("connom"), TEXT("connom_str"), value, m_paraFileName);
m_parameters.at("connom_str").str = (CT2A)value;
m_parameters.at("connom_str").str = m_parameters.at("connom_str").str.substr(1, m_parameters.at("connom_str").str.length() - 2);
nSelD = 33.4;
value.Format(_T("%lf"), nSelD + 1);
WritePrivateProfileString(TEXT("test"), TEXT("test_num"), value, m_paraFileName);
m_parameters.at("test_num").dvalue = nSelD;
value = "\"";
value += "my_stringa";
value += "\"";
WritePrivateProfileString(TEXT("test"), TEXT("test_str"), value, m_paraFileName);
m_parameters.at("test_str").str = (CT2A)value;
m_parameters.at("test_str").str = m_parameters.at("test_str").str.substr(1, m_parameters.at("test_str").str.length() - 2);
}
m_parametersInit = m_parameters;
return TRUE;
}
bool MyWritePrivateProfileString(CString cs1, CString cs2, CString value, CString paraFileName) {
CString str = value;
//CString str = _T("\"中文abc\"");
int u8Len = ::WideCharToMultiByte(CP_UTF8, NULL, str, wcslen(str), NULL, 0, NULL, NULL);
char* szU8 = new char[u8Len + 1];
::WideCharToMultiByte(CP_UTF8, NULL, str, wcslen(str), szU8, u8Len, NULL, NULL);
szU8[u8Len] = '\0';
WritePrivateProfileStringA((CW2A)cs1, (CW2A)cs2, szU8, (CW2A)paraFileName);
return TRUE;
}
bool reWriteParam()
{
auto paramit = m_parameters.begin();
CString value;
for (; paramit != m_parameters.end(); paramit++) {
CString value;
if (paramit->second.type == "int") {
value.Format(_T("%d"), paramit->second.ivalue);
}
else if (paramit->second.type == "double") {
value.Format(_T("%lf"), paramit->second.dvalue);
}
else {
//continue;
value = "\"";
value += paramit->second.str.c_str();
value += "\"";
std::string s1, s2;
CString cs1, cs2;
s2 = paramit->first;
cs2 = s2.c_str();
std::string::size_type pos = s2.find('_');
if (pos != std::string::npos) {
s1 = s2.substr(0, pos);
cs1 = s1.c_str();
MyWritePrivateProfileString(cs1, cs2, value, m_paraFileName);
//WritePrivateProfileString(cs1, cs2, valueL, m_paraFileName);
//WritePrivateProfileString(cs1, cs2, (LPCWSTR)"\"中文\"", m_paraFileName);
//WritePrivateProfileString(cs1, cs2, _T("\"中文\""), m_paraFileName);
//WritePrivateProfileString(cs1, cs2, L"\"中文\"", m_paraFileName);
}
continue;
}
std::string s1, s2;
CString cs1, cs2;
s2 = paramit->first;
cs2 = s2.c_str();
std::string::size_type pos = s2.find('_');
if (pos != std::string::npos) {
s1 = s2.substr(0, pos);
cs1 = s1.c_str();
WritePrivateProfileString(cs1, cs2, value, m_paraFileName);
}
}
return false;
}