2011-12-25 2 views
1

Есть ли эквивалент TryParse в C++ (gcc)?Есть ли эквивалент TryParse в C++ (gcc)?

Я хотел бы проанализировать строку, которая может содержать (+31321), и хранить ее как можно дольше. Я знаю, что телефонные номера хранятся в виде строк и строк, но для моих нужд я хотел бы хранить их так долго, а иногда они могут содержать плюсы (+). Что бы разобрать его на C++?

+1

См http://www.cplusplus.com/reference/clibrary/cstdlib/strtoul/ – tenfour

+1

Проблема с strtoul() - нет признаков сбоя (он просто возвращает 0). –

ответ

3

Проблема с strtoul() и семьей нет реального способа проверить на предмет отказа.
Если он не разбирается, он возвращает 0 без установки errno (который установлен только при переполнении).

повышение лексического литая

#include <boost/lexical_cast.hpp> 


int main() 
{ 
    try 
    { 
     long x = boost::lexical_cast<long>("+1234"); 
     std::cout << "X is " << x << "\n"; 
    } 
    catch(...) 
    { 
     std::cout << "Failed\n"; 
    } 
} 

Делать это с помощью потоков

int main() 
{ 
    try 
    { 
     std::stringstream stream("+1234"); 
     long x; 
     char test; 

     if ((!(stream >> x)) || (stream >> test)) 
     { 
      // You should test that the stream into x worked. 
      // You should also test that there is nothing left in the stream 
      // Above: if (stream >> test) is good then there was content left after the long 
      //   This is an indication that the value you were parsing is not a number. 
      throw std::runtime_error("Failed"); 
     } 
     std::cout << "X is " << x << "\n"; 
    } 
    catch(...) 
    { 
     std::cout << "Failed\n"; 
    } 
} 

Использование зсапЕ:

int main() 
{ 
    try 
    { 
     char integer[] = "+1234"; 
     long x; 
     int len; 

     if (sscanf(integer, "%ld%n", &x, &len) != 1 || (len != strlen(integer))) 
     { 
      // Check the scanf worked. 
      // Also check the scanf() read everything from the string. 
      // If there was anything left it indicates a failure. 
      throw std::runtime_error("Failed"); 
     } 
     std::cout << "X is " << x << "\n"; 
    } 
    catch(...) 
    { 
     std::cout << "Failed\n"; 
    } 
} 
+0

Отличный ответ, но должно быть лучше поймать исключения явно, а не использовать '...', правильно? – tenfour

+0

@tenfour: Абсолютно. Я просто делал это в качестве примера. –

2

+31321 может быть проанализирован как long с обычными операторами извлечения потока.

#include <iostream> 
#include <sstream> 
int main() 
{ 
    std::istringstream s("+31321"); 
    long n; 
    s >> n; 
    std::cout << n << '\n'; 
} 

демо: http://ideone.com/4rmlp

Хотя разборе фактический номер телефона (со скобками, тире, удлинители и т.д.) не могут быть простыми.

1

оператор ввода вывода >> (я надеюсь, что это приемлемое имя) применяется и возвращает поток &, который имеет оператор bool, что означает, что извлечение было успешно предпринято. Например, из Cubbi ответа:

... 
    std::istringstream s("+31321"); 
    long n; 
    if (s >> n) 
     std::cout << n << '\n'; 
.... 

Это succed, конечно, учитывая соответствующее содержание с.

Несколько другое (проще, но не безопасное для типа) также семейство scanf имеет практические инструменты, доступные на C++, а также c. Конечно, вы можете написать на примере так:

... 
    long n; 
    if (sscanf("+31321", "%d", &n) == 1) 
     std::cout << n << '\n'; 
... 

подмножество регулярных выражений сделать это достаточно мощным: например, чтобы соответствовать запятой separed мульти поля с левым пространством обрезки:

if (sscanf("a,b,c", " [^,], [^,], [^,]", a,b,c) == 3) ... 
2

В самом деле , прежде чем преобразовать строку в число, числа должны быть «нормализованы» в общий формат. Это требует удаления всех символов и замены их на правильное представление.

Но вы должны быть очень осторожны с представлением телефонных номеров (которые не являются номерами: они не подвергаются регулярной арифметике) в виде строки: номер, начинающийся с одного или нескольких нулей, не совпадает с номером с удаленными нулями:

00 является типичной заменой для +, но число без знака 00 (или +) спереди должно быть префиксом 00c, где c - код страны.

Перед конвертированием необходимо выполнить некоторую предварительную обработку, чтобы получить равномерное строковое представление, иначе вы рискуете «псевдонимом» разных вещей.

Смежные вопросы