【问题标题】:Convert wide CString to char*将宽 CString 转换为 char*
【发布时间】:2015-08-07 21:21:56
【问题描述】:

这个问题被问了很多次,答案也一样多——没有一个对我有用,而且似乎还有很多其他的。问题是关于 MFC 下的宽 CString 和 8 位字符。我们都想要一个适用于所有情况的答案,而不是特定的实例。

void Dosomething(CString csFileName)
{
    char cLocFileNamestr[1024];
    char cIntFileNamestr[1024];
    // Convert from whatever version of CString is supplied
    // to an 8 bit char string
    cIntFileNamestr = ConvertCStochar(csFileName);

    sprintf_s(cLocFileNamestr, "%s_%s", cIntFileNamestr, "pling.txt" );
    m_KFile = fopen(LocFileNamestr, "wt");
}

这是对现有代码(由其他人编写)的补充,用于调试。 我不想更改函数签名,它在很多地方都使用过。 我无法更改 sprintf_s 的签名,它是一个库函数。

【问题讨论】:

  • 您希望您的 C 风格字符串采用哪种编码方式,以及您想对其中无法表示的字符做什么?
  • 在 MFC 或 Windows 中没有 8 位字符。这些是MBCS 字符,根据特定的Code page 进行解释。字符 - 通常 - 无法正确解释,除非您指定其编码。您的目标字符串应该使用哪种编码?不可表示的字符呢?你为什么不直接打电话给swprintf_s呢?
  • 过度复杂化是这里的一个主要问题。这是为我调试的(不是俄语)。字符将与使用英文字母在英文键盘上键入一样,以使英文有意义。很抱歉重复,但我已经做了很多年了。

标签: c++ mfc char


【解决方案1】:

您遗漏了很多细节,或者忽略了它们。如果您正在使用定义的 UNICODE 进行构建(您似乎是这样),那么转换为 MBCS 的最简单方法是这样的:

CStringA strAIntFileNameStr = csFileName.GetString(); // uses default code page

CStringA 是 CString 的 8 位/MBCS 版本。

但是,如果您要翻译的 unicode 字符串包含不在默认代码页中的字符,它将填充一些垃圾字符。

您可以使用_wfopen(),而不是使用fopen(),这将打开一个具有unicode 文件名的文件。要创建文件名,您可以使用swprintf_s()

【讨论】:

  • 所以,关于 CStrings 的一件事是它很容易转换为传统的 char* 字符串。如果我们试图将这些字符插入的函数是一个只接受 ascii 中的 char* 字符串的遗留函数怎么办?
【解决方案2】:

适用于所有情况的答案,而不是特定实例...

没有这样的事情。

"ABCD..."wchar_t* 转换为 char* 很容易,但它不适用于非拉丁语言。

当您的项目是 unicode 时,请坚持使用 CStringwchar_t

如果你需要上传数据到网页什么的,那么使用CW2ACA2W进行utf-8和utf-16的转换。

CStringW unicode = L"Россия";
MessageBoxW(0,unicode,L"Russian",0);//should be okay

CStringA utf8 = CW2A(unicode, CP_UTF8);
::MessageBoxA(0,utf8,"format error",0);//WinApi doesn't get UTF-8

char buf[1024];
strcpy(buf, utf8);
::MessageBoxA(0,buf,"format error",0);//same problem

//send this buf to webpage or other utf-8 systems
//this should be compatible with notepad etc. 
//text will appear correctly
ofstream f(L"c:\\stuff\\okay.txt");
f.write(buf, strlen(buf));

//convert utf8 back to utf16
unicode = CA2W(buf, CP_UTF8);
::MessageBoxW(0,unicode,L"okay",0);

【讨论】:

  • 再一次,改变功能而不是转换字符。
  • 如果保证是英文的,那么只需使用CStringACStringW在ANSI和Unicode之间来回转换。请参阅乔·威尔考克森的回答。 CString 定义为 CStringWCStringA 取决于 #ifdef _UNICODE
猜你喜欢
  • 2020-06-12
  • 2010-10-25
  • 2015-05-14
  • 1970-01-01
  • 2012-09-17
  • 2015-07-03
  • 2020-04-11
  • 2011-11-02
相关资源
最近更新 更多