2012-06-12 35 views
7

Dưới đây là một số mẫu mã:Đây có phải là lỗi trình biên dịch hay đó là mã của tôi?

#include <iostream> 
#include <stdexcept> 
#include <cstring> 
#include <ctime> 
#include <sstream> 

using std::cout; 
using std::endl; 

std::size_t const BUF_SIZE(1000); 

std::ostream& operator<<(std::ostream& os, std::tm const& rhs) 
{ 
    os << asctime(&rhs); 
    return os; 
} 

std::istream& operator>>(std::istream& is, std::tm& rhs) 
{ 
    while (is.peek() == ' ' || is.peek() == '\t') 
    { 
     is.get(); 
    } 
    std::streampos curPos = is.tellg(); 
    char buf[BUF_SIZE]; 
    is.getline(buf, BUF_SIZE); 
    char* ptr = strptime(buf, "%D %T", &rhs); 
    if (ptr == 0) 
    { 
     throw std::runtime_error("strptime() failed!"); 
    } 
    std::size_t processed = ptr - buf; 
    is.seekg(curPos + static_cast<std::streampos>(processed)); 
    return is; 
} 

int main() 
{ 
    std::istringstream is("10101 07/09/12 07:30:00 123.24"); 
    int uuid(0); 
    double price(0); 
    std::tm ptime; std::memset(&ptime, 0, sizeof(tm)); 

    is >> uuid >> ptime >> price; 
    cout << "UUID: " << uuid << endl; 
    cout << "Time: " << ptime; 
    cout << "Price: " << price << endl; 
} 

nơi tôi đang cố gắng để quá tải < < và >> nhà khai thác cho struct tm! Nếu tôi biên dịch mã bằng g ++ và chạy nó, tôi nhận được:

UUID: 10101 
Time: Sun Jul 9 07:30:00 2012 
Price: 123.24 

Hoàn hảo!

Nhưng, nếu tôi biên dịch nó bằng cách sử kêu vang ++, tôi nhận được:

UUID: 10101 
Time: Sun Jul 9 07:30:00 2012 
Price: 0 

OOPS!

Điều gì đang xảy ra? đây có phải là vấn đề với clang hoặc đó là cách tôi đang xử lý istream?

+0

Tại ideone.com [gcc-4.3.4] (http://ideone.com/UDQEm) và [gcc-4.5.1] (http://ideone.com/NXZqK) tạo ra cùng một kết quả bạn thấy với tiếng kêu. – Blastfurnace

+0

Công việc 'strptime' có hoạt động như thế nào không? Đây là một hàm không chuẩn (POSIX) và tôi không chắc chắn nếu libC++ của clang hỗ trợ nó. – dirkgently

+0

'gcc 4.6.3-1ubuntu5' cho _Perfect! _ Output Reza báo cáo trên hệ thống Ubuntu x86-64 của tôi. – sarnold

Trả lời

9

tôi đã có thể tái sản xuất này (g ++ 4.7.0 và kêu vang ++ 3.1 với libC++ - svn) và một phiên gỡ lỗi ngắn gọn cho thấy kêu vang ++ đặt eofbit sau getline (đó là bình thường), sau đó bằng cách nào đó gây seekg thiết failbit . Điều này nghe có vẻ giống như một lỗi, cho rằng xem kg first clears eofbit (§27.7.2.3/41)

Để làm việc xung quanh, hãy chèn is.clear() vào bất kỳ nơi nào giữa getlineseekg.

+2

PS: từ ngữ này là mới trong C++ 11, C++ 03 đã không nói điều đó và trên thực tế làm cho nó nghi ngờ rằng chúng ta có thể tìm cách xa eof: [LWG vấn đề 342] (http: //cplusplus.github. com/LWG/lwg-closed.html # 342) – Cubbi

+3

PS/2: Đã gửi: http://llvm.org/bugs/show_bug.cgi?id=13089 – Cubbi

Các vấn đề liên quan