2012-06-26 4 views
0

Как сделать переводконвертировать дату и время в целые числа в C++

std :: string strdate = "2012-06-25 05: 32: 06.963";

В какой-то вещи, как этот

станд :: струнной strintdate = "20120625053206963" // в основном я удалил -,:, пробел и.

Я думаю, что я должен использовать strtok или строковые функции, но я не в состоянии это сделать, может кто-нибудь, пожалуйста, помогите мне здесь с кодом сампеля.

так, что я преобразовать его в беззнаковое __int64 с помощью

// crt_strtoui64.c 
#include <stdio.h> 

unsigned __int64 atoui64(const char *szUnsignedInt) { 
    return _strtoui64(szUnsignedInt, NULL, 10); 
} 

int main() { 
    unsigned __int64 u = atoui64("18446744073709551615"); 
    printf("u = %I64u\n", u); 
} 
+0

использовать цикл и собрать цифры до преобразования? Или используйте regex в C++ 11 – nhahtdh

ответ

3
bool nondigit(char c) { 
    return c < '0' || c > '9'; 
} 

std::string strdate = "2012-06-25 05:32:06.963"; 
strdate.erase(
    std::remove_if(strdate.begin(), strdate.end(), nondigit), 
    strdate.end() 
); 

std::istringstream ss(strdate); 
unsigned __int64 result; 
if (ss >> result) { 
    // success 
} else { 
    // handle failure 
} 

Btw, ваше представление в виде 64-разрядного int может быть немного хрупким. Убедитесь, что дата/время 2012-06-25 05:32:06 введено как 2012-06-25 05:32:06.000, в противном случае целое число, которое вы получаете из конца, меньше, чем ожидалось (и, следовательно, может быть путано для даты/времени в году 2AD).

+0

Почему бы не использовать 'isdigit()'? – jrok

+0

@jrok: потому что он специфичен для локали, и я не помню, является ли 'operator >>' тоже. Также потому, что 'isdigit' не принимает отрицательный вход, так что вам нужен дополнительный бросок и дополнительное объяснение, чтобы пойти с ним. Тем не менее, существует версия шаблона 'isdigit' в' ', что позволяет избежать последней проблемы за счет (для меня, во всяком случае) необходимости искать ее перед ее использованием. –

+0

Делает смысл, ти. – jrok

0

Здесь вы идете:

bool not_digit (int c) { return !std::isdigit(c); } 

std::string date="2012-06-25 05:32:06.963"; 
// construct a new string 
std::string intdate(date.begin(), std::remove_if(date.begin(), date.end(), not_digit)); 
0

я бы не использовать strtok. Вот довольно простой метод, который использует только std::string функции-члены:

std::string strdate = "2012-06-25 05:32:06.963"; 
size_t pos = strdate.find_first_not_of("1234567890"); 
while (pos != std::string::npos) 
{ 
    size_t endpos = strdate.find_first_of("1234567890", pos); 
    strdate.erase(pos, endpos - pos); 
    pos = strdate.find_first_not_of("1234567890"); 
} 

Это не очень эффективный подход, но он будет работать.

, возможно, более эффективный подход может использовать stringstream ...

std::string strdate = "2012-06-25 05:32:06.963"; 

std::stringstream out; 

for (auto i = strdate.begin(); i != strdate.end(); i++) 
    if (std::isdigit(*i)) out << *i; 

strdate = out.str(); 

Я не делаю никаких обещаний о времени или пространстве сложности, но я подозреваю, что использование string::erase несколько раз может включать в себя немного больше перетасовки памяти.

2

Если ваш компилятор поддерживает C++ 11 особенности:

#include <iostream> 
#include <algorithm> 
#include <string> 

int main() 
{ 
    std::string s("2012-06-25 05:32:06.963"); 
    s.erase(std::remove_if(s.begin(), 
          s.end(), 
          [](const char a_c) { return !isdigit(a_c); }), 
      s.end()); 
    std::cout << s << "\n"; 
    return 0; 
} 
0
std::string strdate = "2012-06-25 05:32:06.963"; 
std::string result =""; 
for(std::string::iterator itr = strdate.begin(); itr != strdate.end(); itr++) 
{ 
    if(itr[0] >= '0' && itr[0] <= '9') 
    { 
     result.push_back(itr[0]); 
    } 
} 
Смежные вопросы