作为 this 的后续行动问题(Message compiler replacement in Linux gcc),我有以下问题:
当在 Windows 上使用 MC.exe 编译和生成消息时,我在 C++ 代码中调用 FormatMessage,它检索消息并使用 va_list *Arguments
参数发送各种消息参数。
例如:
messages.mc 文件:
MessageId=1
Severity=Error
SymbolicName=MULTIPLE_MESSAGE_OCCURED
Language=English
message %1 occured %2 times.
.
C++代码:
void GetMsg(unsigned int errCode, wstring& message,unsigned int paramNumber, ...)
{
HLOCAL msg;
DWORD ret;
LANGID lang = GetUserDefaultLangID();
try
{
va_list argList;
va_start( argList, paramNumber );
const TCHAR* dll = L"MyDll.dll";
_hModule = GetModuleHandle(dll);
ret =::FormatMessage(
FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_HMODULE|FORMAT_MESSAGE_IGNORE_INSERTS,
_hModule,
errCode,
lang,
(LPTSTR) &msg,
0,
&argList );
if ( 0 != ret )
{
unsigned int count = 0 ;
message = msg;
if (paramNumber>0)
{
wstring::const_iterator iter;
for (iter = message.begin();iter!=message.end();iter++)
{
wchar_t xx = *iter;
if (xx ==L'%')
count++;
}
}
if ((count == paramNumber) && (count >0))
{
::LocalFree( msg );
ret =::FormatMessage(
FORMAT_MESSAGE_ALLOCATE_BUFFER |
FORMAT_MESSAGE_FROM_HMODULE,
_hModule,
errCode,
GetUserDefaultLangID(),
(LPTSTR) &msg,
0,
&argList );
}
else if (count != paramNumber)
{
wstringstream tmp;
wstring messNumber;
tmp << (errCode & 0xFFFF);
tmp >> messNumber;
message = message +L"("+ messNumber + L"). Bad Format String. ";
}
}
::LocalFree( msg );
}
catch (...)
{
message << L"last error: " << GetLastError();
}
va_end( argList );
}
调用方代码:
wstring message;
GetMsg(MULTIPLE_MESSAGE_OCCURED, message,2, "Error message", 5);
现在,我编写了一个简单的脚本来从 .mc 文件生成一个 .msg 文件,然后我使用 gencat 从它生成一个目录。
但是有没有办法使用格式化字符串,因为它们包含 %1、%2 等,而不是一般的(%d、%s...)格式?
请注意,对于每个可能的消息和每个可能的类型\参数顺序,解决方案必须足够通用...
有可能吗?
谢谢。
最佳答案
首先像printf这样的函数支持定位格式:
printf("%2$s, %1$d", salary, name);
对于 C++,除了 C 解决方案之外还有一个 boost::format
库:
std::cout << boost::format("%2%, %1%") % salary % name;
此外,如果您要将软件转移到 Linux,我建议使用“不同”的本地化方法:使用 gettext 或 boost.locale 库。
而不是这个:
wstring message;
GetMsg(MULTIPLE_MESSAGE_OCCURED, message,2, "Error message", 5);
使用:
C/gettext:
snprintf(msg,sizeof(msg),gettext("This is the message to %1$s about %2$s"),who,what);
C++/gettext:
using boost::format;
std::ostringstream ss;
ss << format(gettext("This is the message to %1% about %2%")) % who % what;
使用 boost.locale 的 C++:
using boost::locale::format;
using boost::locale::translate;
std::ostringstream ss;
ss << format(translate("This is the message to {1} about {2}")) % who % what;
关于c++ - 使用包含 %1、%2 等而不是 %d、%s 等的格式字符串 - Linux、C++,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4533534/