2012-06-08 38 views
7

Tôi muốn kiểm soát xem ostream xuất ra của char s và unsigned char 's của tôi qua << viết chúng như ký tự hoặc số nguyên. Tôi không thể tìm thấy một tùy chọn như vậy trong thư viện chuẩn. Hiện tại, tôi đã hoàn nguyên về việc sử dụng nhiều lần quá tải trên một tập hợp các chức năng in thay thếchars in ấn như Số nguyên

ostream& show(ostream& os, char s) { return os << static_cast<int>(s); } 
ostream& show(ostream& os, unsigned char s) { return os << static_cast<int>(s); } 

Có cách nào tốt hơn không?

+1

Bạn có muốn luôn luôn để in ký tự là số nguyên hoặc tùy thuộc vào một điều kiện? – Andrey

+0

Tôi muốn nó phụ thuộc vào điều kiện (trạng thái) tương tự như cờ trạng thái 'ios'. –

+4

Tôi không hiểu sự cần thiết phải phân biệt chữ ký và unsigned char. Nếu bạn muốn xuất nó dưới dạng một số, hãy đặt nó dưới dạng int trước. Nếu không, chỉ cần in nó vào os. – Neil

Trả lời

0

Tôi có một đề nghị dựa trên các kỹ thuật được sử dụng trong how do I print an unsigned char as hex in c++ using ostream?.

template <typename Char> 
struct Formatter 
    { 
    Char c; 
    Formatter(Char _c) : c(_c) { } 

    bool PrintAsNumber() const 
    { 
    // implement your condition here 
    } 
    }; 

template <typename Char> 
std::ostream& operator<<(std::ostream& o, const Formatter<Char>& _fmt) 
    { 
    if (_fmt.PrintAsNumber()) 
    return (o << static_cast<int>(_fmt.c)); 
    else 
    return (o << _fmt.c); 
    } 

template <typename Char> 
Formatter<Char> fmt(Char _c) 
    { 
    return Formatter<Char>(_c); 
    } 

void Test() 
    { 
    char a = 66; 
    std::cout << fmt(a) << std::endl; 
    } 
+0

Bạn nhận ra tất nhiên là bạn đã viết 23 dòng mã (không bao gồm trình kiểm tra) để có thể in một ký tự dưới dạng số, đúng không? Không phải là một chút overkill? – Neil

1

Không, không có cách nào tốt hơn. Một cách tốt hơn sẽ lấy mẫu của trình xử lý luồng tùy chỉnh, như std::hex. Sau đó, bạn có thể tắt và bật số nguyên của bạn mà không cần phải chỉ định nó cho mỗi số. Nhưng các thao tác tùy chỉnh hoạt động trên chính luồng đó và không có bất kỳ format flags nào để thực hiện những gì bạn muốn. Tôi cho rằng bạn có thể viết luồng của riêng bạn, nhưng đó là cách làm việc nhiều hơn bạn đang làm bây giờ.

Thành thực mà nói, đặt cược tốt nhất của bạn là để xem nếu soạn thảo văn bản của bạn có chức năng để làm static_cast<int> dễ dàng hơn để gõ. Tôi cho rằng bạn sẽ đánh máy rất nhiều hoặc bạn sẽ không hỏi. Bằng cách đó, ai đó đọc mã của bạn biết chính xác ý bạn là gì (tức là in một char như một số nguyên) mà không phải tra cứu định nghĩa của hàm tùy chỉnh.

+0

+1 cho câu trả lời mang lại sự đơn giản. – Neil

0

Chỉ cập nhật cho bài đăng cũ. Bí quyết thực tế đang sử dụng '+'. Ví dụ:

template <typename T> 
void my_super_function(T x) 
{ 
    // ... 
    std::cout << +x << '\n'; // promotes x to a type printable as a number, regardless of type 
    // ... 
} 

Trong C++ 11 bạn có thể làm:

template <typename T> 
auto promote_to_printable_integer_type(T i) -> decltype(+i) 
{ 
    return +i; 
} 

Credit: How can I print a char as a number? How can I print a char* so the output shows the pointer’s numeric value?