我正在使用Windows API GetNumberFormatEx格式化某些数字以显示当前用户的相应本地化选项(例如,确保它们在正确的位置具有正确的分隔符)。当您想要完全符合用户默认值时,这是微不足道的。
但在某些情况下,我有时必须覆盖基数分隔符后面的位数。这需要提供NUMBERFMT结构。我想要做的是调用一个API,返回为用户填充适当默认值的NUMBERFMT,然后只覆盖我需要更改的字段。但似乎没有API来获取默认值。
目前,我一遍又一遍地调用GetLocaleInfoEx,然后将该数据转换为NUMBERFMT所需的格式。
NUMBERFMT fmt = {0};
::GetLocaleInfoEx(LOCALE_NAME_USER_DEFAULT,
LOCALE_IDIGITS | LOCALE_RETURN_NUMBER,
reinterpret_cast<LPWSTR>(&fmt.NumDigits),
sizeof(fmt.NumDigits)/sizeof(WCHAR));
::GetLocaleInfoEx(LOCALE_NAME_USER_DEFAULT,
LOCALE_ILZERO | LOCALE_RETURN_NUMBER,
reinterpret_cast<LPWSTR>(&fmt.LeadingZero),
sizeof(fmt.LeadingZero)/sizeof(WCHAR));
WCHAR szGrouping[32] = L"";
::GetLocaleInfoEx(LOCALE_NAME_USER_DEFAULT, LOCALE_SGROUPING, szGrouping,
ARRAYSIZE(szGrouping));
if (::lstrcmp(szGrouping, L"3;0") == 0 ||
::lstrcmp(szGrouping, L"3") == 0
) {
fmt.Grouping = 3;
} else if (::lstrcmp(szGrouping, L"3;2;0") == 0) {
fmt.Grouping = 32;
} else {
assert(false); // unexpected grouping string
}
WCHAR szDecimal[16] = L"";
::GetLocaleInfoEx(LOCALE_NAME_USER_DEFAULT, LOCALE_SDECIMAL, szDecimal,
ARRAYSIZE(szDecimal));
fmt.lpDecimalSep = szDecimal;
WCHAR szThousand[16] = L"";
::GetLocaleInfoEx(LOCALE_NAME_USER_DEFAULT, LOCALE_STHOUSAND, szThousand,
ARRAYSIZE(szThousand));
fmt.lpThousandSep = szThousand;
::GetLocaleInfoEx(LOCALE_NAME_USER_DEFAULT,
LOCALE_INEGNUMBER | LOCALE_RETURN_NUMBER,
reinterpret_cast<LPWSTR>(&fmt.NegativeOrder),
sizeof(fmt.NegativeOrder)/sizeof(WCHAR));
是否有API已经执行此操作?
答案 0 :(得分:2)
我上周刚写了一些代码来做这件事。唉,似乎没有GetDefaultNumberFormat(LCID lcid,NUMBERFMT * fmt)函数;你必须自己编写,因为你已经开始了。另外,分组字符串具有明确定义的格式,可以轻松解析;你的当前代码对于“3”(应该是30)是错误的,并且显然会在更多异国情调的分组上失败(尽管这可能不是很关心,真的)。
答案 1 :(得分:0)
如果您要做的只是剪切字符串末尾的小数位,您可以使用其中一种默认格式(如LOCALE_NAME_USER_DEFAULT
),然后检查是否存在小数分隔符(在生成的字符串中使用大陆语言中的逗号(以英语表示),然后通过将其替换为空字节来删除小数部分:
#define cut_off_decimals(sz, cch) \
if (cch >= 5 && (sz[cch-4] == _T('.') || sz[cch-4] == _T(','))) \
sz[cch-4] = _T('\0');
(匈牙利警报:sz
是C字符串,cch
是字符数,包括终止空字节。_T
是char
的Windows通用文本makro }或wchar_t
取决于是否定义了UNICODE
,仅在与Windows 9x / ME兼容时才需要。)
请注意,对于用户定义格式的非常奇怪的情况,这会产生错误的结果,其中倒数第三个字符是点或逗号,对用户有一些特殊含义小数分隔符以外的内容。我一生中从未见过如此数字的格式,因此我得出结论认为这是好的和安全的。
当然,如果第三个到最后一个字符既不是点也不是逗号,这将不起作用。