2014-09-08 2 views
4

Если я простой объект даты:C++ Печати объекта несколько способов

#include <iostream> 
using namespace std; 

class Date 
{ 
    int mo, da, yr; 
public: 
    Date(int m, int d, int y) 
    { 
     mo = m; da = d; yr = y; 
    } 
    friend ostream& operator<<(ostream& os, const Date& dt); 
}; 

ostream& operator<<(ostream& os, const Date& dt) 
{ 
    os << dt.mo << '/' << dt.da << '/' << dt.yr; 
    return os; 
} 

int main() 
{ 
    Date dt(5, 6, 92); 
    cout << dt; 
} 

, и я хочу, чтобы иметь возможность печатать его в том, как люди из Великобритании поймет, т.е.

ostream& operator<<(ostream& os, const Date& dt) 
{ 
    os << dt.da << '/' << dt.mo << '/' << dt.yr; 
    return os; 
} 

Как наилучшим образом разрешить пользователям класса выбирать между двумя (или более) параметрами печати?

Я думал о чем-то подобном возвращению двух отдельных классов из двух методов класса даты, каждый из которых имеет свой оператор < <, перегруженный двумя разными способами. Но есть ли лучший способ?

код из: http://msdn.microsoft.com/en-us/library/1z2f6c2k.aspx

+0

Существует ли 'strftime' в вашей системе? –

+1

Проверьте информацию о культуре для ОС и используйте ее в потоковом операторе. Альтернативно, есть статический член для выбора формата? – crashmstr

+1

Должен взглянуть на язык: http://www.cplusplus.com/reference/locale/ – Christophe

ответ

4

Вы должны реализовать manipulator.

Уверен, что в C++ есть поддержка для реализации ваших собственных. Для вдохновения посмотрите, как, например, std::showbase/std::noshowbase реализован в вашей среде. Вам нужно будет реализовать ukdate/noukdate.

Редактировать: showbase действительно слишком узкий пример для этого - нам нужно будет выделить однопотоковое слово, используя std::ios_base::xalloc.

+0

'showbase' /' noshowbase', установив/сняв флажок формата потока. Это объяснение, предназначенное для этой цели. Какой флаг вы бы установили для 'ukdate' /' noukdate'? –

+1

Вам нужно будет использовать std :: ios_base :: xalloc – Arkadiy

9

культуры в зависимости от потока форматирования (например, дат, денежных) должна основываться на std::locale настройки данного потока:

#include <locale> 
#include <ostream> 

std::ostream& operator<<(std::ostream& os, const Date& dt) 
{ 
    std::time_base::dateorder d = std::use_facet<std::time_get<char>>(os.getloc()) 
             .date_order(); 

    if (d == std::time_base::dmy) 
    { 
     // Selected format is day/month/year 
     os << dt.da << '/' << dt.mo << '/' << dt.yr; 
    } 
    else if (d == std::time_base::mdy) 
    { 
     // Selected format is month/day/year 
     os << dt.mo << '/' << dt.da << '/' << dt.yr; 
    } 
    else 
    { 
     // Default format is year . month . day 
     os << dt.yr << '.' << dt.mo << '.' << dt.da; 
    } 

    return os; 
} 

Это позволяет пользователям вашего класса, чтобы выбрать между различными форматами (предполагающей языковой стандарт поддерживается), так что мощность регулируется для данной культуры:

Date d{ 9, 8, 2014 }; 

std::cout.imbue(std::locale("en_US.utf8")); 
std::cout << d << std::endl; 

std::cout.imbue(std::locale("de_DE.utf8")); 
std::cout << d << std::endl; 

DEMO

+0

Может быть лучше использовать 'imbue' /' getloc'? – Arkadiy

+0

@Arkadiy Я использую imbue/getloc –

+0

А - так вы есть. Благодарю. – Arkadiy

Смежные вопросы