#c# #c
#c# #c
Вопрос:
Я пытаюсь найти эквивалент C # следующего в C . Это чисто для развлечения
#include <iomanip>
#include <iostream>
#include <tchar.h>
class CommaSep : public std::numpunct<TCHAR>
{
public:
CommaSep(TCHAR thousands_sep, const char* grouping)
:m_thousands_sep(thousands_sep),
m_grouping(grouping){}
protected:
TCHAR do_thousands_sep() const{return m_thousands_sep;}
std::string do_grouping() const {return m_grouping;}
private:
TCHAR m_thousands_sep;
std::string m_grouping;
};
int main()
{
double number = 1234567.1235;
std::locale comma_locale(std::locale(), new CommaSep(_T(','), "3"));
std::locale indian_locale(std::locale(), new CommaSep(_T(','), "223"));
std::locale weird_locale(std::locale(), new CommaSep(_T(','), "213"));
std::wcout.imbue(comma_locale);
std::wcout << std::setprecision(2) << std::fixed << number << std::endl;
std::wcout.imbue(indian_locale);
std::wcout << std::setprecision(2) << std::fixed << number << std::endl;
std::wcout.imbue(weird_locale);
std::wcout << std::setprecision(2) << std::fixed << number << std::endl;
}
В результате получается
1,234,567.12
123,45,67.12
1,234,5,67.12
Он делает именно то, что я ему говорю. Я попробовал следующее в C #. Код намного меньше (ура), но компилятор просто игнорирует форматирование и делает свое дело (шипение)
namespace imbuecs
{
class Imbue
{
static void Main(string[] args)
{
int bignum = 123456789;
System.Console.WriteLine(bignum.ToString("########0"));
// Indian
System.Console.WriteLine(bignum.ToString("##,###,##,#0"));
System.Console.WriteLine(bignum.ToString("###,###,##0"));
// Chinese
System.Console.WriteLine(bignum.ToString("#,####,###0"));
}
}
}
То, что я получил, было
123456789
123,456,789 expected 12,345,67,89
123,456,789
123,456,789 expected 1,2345,6789
Я могу написать огромные участки кода для этого, но мне интересно, есть ли простой способ сделать это.
Комментарии:
1. «намного меньше» — вы могли бы написать совершенно неправильный код и на C , и он тоже был бы короче 🙂 .. Если вам действительно важно, вы должны использовать соответствующее
CultureInfo
форматирование, зависящее от локали, а не какое-то ручное решение.2. CultureInfo не будет использовать странный язык, для чего я обычно его использую. Иногда мне приходится отображать разделители в нестандартных позициях.
Ответ №1:
Из документации, при указании пользовательского форматирования, запятая (курсив мой):
Служит как разделителем групп, так и спецификатором масштабирования чисел. В качестве разделителя групп он вставляет локализованный символ разделителя групп между каждой группой. В качестве спецификатора масштабирования чисел он делит число на 1000 для каждой указанной запятой.
Таким образом, это приводит к тому, что число группируется в 3 цифры. Если вы хотите создать свой собственный формат, вам нужно заключить запятую в одинарные кавычки, чтобы отобразить ее как буквальную строку. Например:
Console.WriteLine(bignum.ToString("##','###','##','#0"));
Console.WriteLine(bignum.ToString("#','####','###0"));
Будет выводить:
12,345,67,89
1,2345,6789
Другой альтернативой является использование NumberFormatInfo
объекта со свойством NumberGroupSizes . Например:
var nfi = new System.Globalization.NumberFormatInfo();
//First group is 2 digits, the rest are 3 digits
nfi.NumberGroupSizes = new int[] { 2, 3 };
Console.WriteLine(bignum.ToString("#,#0", nfi));