2016-09-16 73 views
-1

我的想法是使用STL并将PWCHAR时间戳转换为wstring,将其加载到流中并使用>>运算符将给定的拆分分配到SYSTEMTIME结构的相应成员中并将其转换为Win32函数到FILETIME结构。如何将PWCHAR转换为FILETIME结构?

VOID StringToFileTime(const PWCHAR timeString, FILETIME &ft) { 
    if(NULL == timeString) 
     return; 

    wstring time(L"2013-May-14 20:33:13.132814"); 
    std::wistringstream stream(time); 
    SYSTEMTIME st = {0}; 
    stream >> st.wYear; 
    stream.ignore(1, '-'); 
    stream >> st.wMonth; 
    stream.ignore(1, '-'); 
    stream >> st.wDay; 
    stream.ignore(1, ' '); 
    stream >> st.wHour; 
    stream.ignore(1, ':'); 
    stream >> st.wMinute; 
    stream.ignore(1, ':'); 
    stream >> st.wSecond; 
    stream.ignore(1, '.'); 
    stream >> st.wMilliseconds; 

    SystemTimeToFileTime(&st, &ft); 
} 

我遇到的问题是SYSTEMTIME结构在st.wYear后没有被填写。所以今年会在2013年设定,但之后的会员为0. 看着变量的内容,我变得更加困惑。硬编码的时间戳不会出现在调试器变量视图的wstring时间变量中。相反,会有一个nPOS编号和时间变量列出的错误。

如何将字符串转换为FILETIME结构?

我使用Visual Studio 2013更新3在Windows 10

enter image description here

+1

尝试一些调试。堆栈溢出不存在为个人执行基本的调试任务。 –

+0

它是一个合法的编程问题。我如何x?这是我所做的尝试。如果它那么基本的大卫,你为什么不回答这个问题? –

+0

你为什么不学习如何调试?你不想这样做吗? –

回答

1

的问题是,stream >> st.wMonth失败,因为它试图读取该字符串值May成数字WORD,这是不支持转换。您没有重置stream错误状态,因此>>ignore()的后续使用也会失败,因此在wYear之后SYSTEMTIME不会填写。

如果你有一个C++编译器11,可以使用std::get_time()解析timeString

#include <sstream> 
#include <iomanip> 

bool StringToFileTime(LPCWSTR timeString, FILETIME &ft) 
{ 
    SYSTEMTIME st = {0}; 

    std::wistringstream stream(timeString); 
    std::tm tmb; 

    // std::get_time() does not support reading milliseconds... 
    if (!(stream >> std::get_time(&tmb, L"%Y-%b-%d %H:%M:%S"))) 
     return false; 

    st.wYear = 1900 + tmb.tm_year; 
    st.wMonth = tmb.tm_mon + 1; 
    st.wDayOfWeek = tmb.tm_wday; 
    st.wDay = tmb.tm_mday; 
    st.wHour = tmb.tm_hour; 
    st.wMinute = tmb.tm_min; 
    st.wSecond = tmb.tm_sec; 

    if (!stream.eof()) 
    { 
     stream.ignore(1, L'.'); 

     // st.wMilliseconds is a 16bit WORD, so it can only go up to 65535. 
     // There are only 1000 ms in a second, so 132814 is clearly not 
     // expressed in milliseconds. Is it nanoseconds? 100-nanoseconds? 
     // Whatever it is, convert it to st.wMilliseconds as needed... 

     int iValue; 
     if (!(stream >> iValue)) 
      return false; 

     st.wMilliseconds = ...; 
    } 

    return SystemTimeToFileTime(&st, &ft); 
} 

如果你没有一个C++编译器11,你仍然可以使用std::wistringstream,你只要必须手动提取值:

#include <sstream> 

bool StringToFileTime(LPCWSTR timeString, FILETIME &ft) 
{ 
    SYSTEMTIME st = {0}; 

    std::wistringstream stream(timeString); 
    std::string sMonth; 

    if (!(stream >> st.wYear)) return false; 
    if (!stream.ignore(1, L'-')) return false; 

    // st.wMonth is a 16bit WORD, but a month name is given instead. 
    // parse it into st.wMonth as needed... 
    if (!std::getline(stream, sMonth, L'-')) return false; 
    st.wMonth = ...; 

    if (!stream.ignore(1, L'-')) return false; 
    if (!(stream >> st.wDay)) return false; 
    if (!stream.ignore(1, L' ')) return false; 
    if (!(stream >> st.wHour)) return false; 
    if (!stream.ignore(1, L':')) return false; 
    if (!(stream >> st.wMinute)) return false; 
    if (!stream.ignore(1, L':')) return false; 
    if (!(stream >> st.wSecond)) return false; 

    if (!stream.eof()) 
    { 
     stream.ignore(1, L'.'); 

     // convert to st.wMilliseconds as needed... 

     int iValue; 
     if (!(stream >> iValue)) 
      return false; 

     st.wMilliseconds = ...; 
    } 

    return SystemTimeToFileTime(&st, &ft); 
} 

或者,你可以使用swscanf()代替std::wistringstream

bool StringToFileTime(LPCWSTR timeString, FILETIME &ft) 
{ 
    SYSTEMTIME st = {0}; 
    WCHAR szMonth[12]; 
    int iValue = 0; 

    int numRead = swscanf(timeString, L"%hu-%[^-]-%hu &hu:&hu:&hu.%d", &st.wYear, szMonth, &st.wDay, &st.wHour, &st.wMinute, st.wSecond, &iValue); 

    if (numRead < 6) return false; 

    // parse szMonth into st.wMonth as needed... 

    if (numRead == 7) 
    { 
     // convert iValue into st.wMilliseconds as needed... 
    } 

    return SystemTimeToFileTime(&st, &ft); 
}