سؤال

في C ++ لقد حصلت على تعويم / المتغير المزدوج.

عند I طباعة هذا على سبيل المثال مع cout السلسلة الناتجة غير محدد الفترة.

cout << 3.1415 << endl
$> 3.1415

هل هناك طريقة سهلة لقوة الضعف التي سيتم طباعتها مع فاصلة؟

cout << 3.1415 << endl
$> 3,1415
هل كانت مفيدة؟

المحلول

وimbue() cout مع locale الذي الدالة العضو numpunct وجه لإرجاع فاصلة decimal_point().

والحصول على مثل هذا locale يمكن أن يتم بعدة طرق. هل يمكن استخدام اسمه لغة المتاحة على النظام الخاص بك (std::locale("fr")، ربما). بدلا من ذلك، هل يمكن أن تستمد numpuct بنفسك، تنفيذ عضو do_decimal_point() في ذلك.

ومثال على النهج الثاني:

template<typename CharT>
class DecimalSeparator : public std::numpunct<CharT>
{
public:
    DecimalSeparator(CharT Separator)
    : m_Separator(Separator)
    {}

protected:
    CharT do_decimal_point()const
    {
        return m_Separator;
    }

private:
    CharT m_Separator;
};

والمستخدمة على النحو التالي:

std::cout.imbue(std::locale(std::cout.getloc(), new DecimalSeparator<char>(',')));

نصائح أخرى

وتحتاج إلى impue تيار مع لغة مختلفة، واحد الذي num_punct (IIRC) يحدد وجه فاصلة.

إذا النظام الأساسي الخاص بك صيغ لغة بفواصل، ثم

cout.imbue(locale(""));

ويجب أن تكون كافية.

ويتم التحكم بذلك عن طريق لغة البرنامج الخاص بك.

وكيف قمت بتعيين اللغة الافتراضية برنامج تعتمد على المنصة. على منصات نوع POSIX، انها مع متغيرات البيئة LANG وLC_ *، على سبيل المثال.

ويمكنك فرض لغة معينة - مختلفة من الافتراضي - ضمن برنامج C ++ من خلال الدعوة دائرة الرقابة الداخلية :: إضفاء. شيء من هذا القبيل يمكن أن تعمل:

#include <locale>
cout.imbue(std::locale("German_germany"));

والفكرة هي لفرض لغة حيث فاصلة هو الفاصل العشري. قد تحتاج إلى ضبط سلسلة "German_germany" للحصول على السلوك الذي تريده على منصة التشغيل الخاصة بك.

لتكون دقيقة، يتم التحكم بذلك عن طريق قيمة std::numpunct<charT>::decimal_point(). يمكنك imbue() لغة أخرى مع decimal_point() آخر

وقديم موضوع، ولكن على أي حال ... وينبغي للمرء أن يكون على علم بأن استخدام std::locale يجعل السلسلة "جميلة"، مع استكمال العشرية الصحيحة، فواصل الآلاف وليس ما، استنادا إلى النظام الأساسي واللغة. على الأرجح، وذلك باستخدام imbue() سوف كسر أي إعراب السلسلة بعد انها تنسيقه. على سبيل المثال:

std::ostringstream s;
std::locale l("fr-fr");
s << "without locale: " << 1234.56L << std::endl;
s.imbue(l);
s << "with fr locale: " << 1234.56L << std::endl;
std::cout << s.str();

ويعطي الإخراج التالية:
without locale: 1234.56
with fr locale: 1 234,56

وعن طريق strtod() أو ما شابه ذلك على السلسلة الثانية ربما لن تعمل بشكل جيد جدا ... أيضا، والمسافة بين "1" و "2" في سلسلة الإخراج الثانية هو غير كسر واحد، مما يجعل من سلسلة حتى أجمل : -)

وموضوع قديم جدا، ولكن على أي حال ... كان لي مشكلة لملء إدخال النص تحت Gtkmm-3.0 مع نتائج حساب المسافة. لجعل الأمور أكثر وضوحا أود أن أضيف مثالا على ذلك، حيث كنت قد ركزت بعض المزج من عدة وظائف قرأت في الأيام الأخيرة:

#include <locale>
// next not necessary, added only for clarity
#include <gtkmm-3.0/gtkmm.h>
Gtk::Entry m_Text;
// a distance measured in kilometers
double totalDistance = 35.45678;
std::stringstream str;
// I am using locale of Germany, pay attention to the _
str.imbue(std::locale("de_DE"));
// now we have decimal comma instead of point
str << std::fixed << std::setprecision(4) << std::setw(16) << totalDistance << " km";
// the wished formatting corresponds to "%16.4f km" in printf
m_Text.set_text(str.str());
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top