2017-07-28 22 views
2

我想解析日期字符串與std::get_time(),但它似乎代碼在VC++ 2015工作,但不工作在gcc 6.3和鐺4.0。這裏是MCVE:std :: get_time()在gcc 6.3和鏗鏘4.0不適用於完整的月份名稱

#include <iostream> 
#include <sstream> 
#include <string> 
#include <iomanip> 

int main() { 

    std::string line = "February 4 1993 15:21"; 

    std::tm date_1 = {}; 

    std::stringstream ss(line); 

    ss >> std::get_time(&date_1, "%b %d %Y %H:%M"); 

    if(ss.fail()) 
    { 
     std::cout << "parse failed\n"; 
    } 

    std::cout << date_1.tm_year << "\n"; 
    std::cout << date_1.tm_mon << "\n"; 
    std::cout << date_1.tm_mday << "\n"; 
    std::cout << date_1.tm_hour << "\n"; 
    std::cout << date_1.tm_min << "\n"; 

    return 0; 
} 

下面是VC++ 2015年的結果:

93 
1 
4 
15 
21 

下面是GCC 6.3.2和4.0鏗鏘(我用的ideone.comColiru編譯器)的結果 - 既沒有C++ 14米的標誌:

parse failed 
0 
1 
0 
0 
0 

它的工作,當我使用月份的縮寫,如二月,八月等

我試過在stringstreamen_US,en_GB + UTF-8版本)上設置不同的語言環境,但它們沒有任何區別或導致運行時錯誤。我試過改變分隔符,但也沒有區別。

我在CPP Reference閱讀%B在std::get_time()

解析月份名稱,要麼全或縮寫,例如十月

這是一個bug在GCC和鐺或者編譯器,相反,什麼是上面寫的,免費辦理只縮寫名稱取決於執行/缺少的功能?標準對此有何評論?這兩個編譯器在這裏表現出相同的行爲是巧合嗎?

+1

libstdC++的錯誤。 [與clang -stdlib = libC++一起使用。](http://coliru.stacked-crooked.com/a/3108a8e1c8921d9a) – cpplearner

+1

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=78714 – cpplearner

+0

謝謝。如果您將它作爲答案發布,我會接受它。 – KjMag

回答

2

正如在評論中指出的那樣,這是一個libstdC++錯誤。然而,沒有注意到如何解決它。

使用%B而不是%b,libstdC++將執行解析。對於解析,%B%b應該具有相同的行爲。但對於格式化,%B輸出區域的全月名稱,而%b格式化縮寫的月份名稱。

最後,你可能有興趣在Howard Hinnant's free, open-source date-time library其允許直接解析成<chrono>時間點和持續時間:

#include "date.h" 
#include <iostream> 
#include <sstream> 

int 
main() 
{ 
    using namespace date; 
    using namespace std::chrono; 
    std::istringstream in{"February 4 1993 15:21"}; 
    sys_time<minutes> tp; 
    in >> parse("%B %d %Y %H:%M", tp); 
    if (in.fail()) 
     return 1; 
    std::cout << tp << '\n'; 
} 

輸出:

1993-02-04 15:21 

在上述sys_time<minutes>的例子是一個類型別名爲std::chrono::time_point<std::chrono::system_clock, std::chrono::minutes>