Private-Bookers
C++. Сборник рецептов
вернуться

Когсуэлл Джефф

Шрифт:

Чтобы выполнить операцию «меньше чем» и «больше чем», вначале проверьте, не равны ли значения, как это делается в функции

doubleEquals
. Если так, то при наличии теста на равенство верните
true
, а в противном случае —
false
. В противном случае выполните прямое сравнение.

3.5. Лексический анализ строки, содержащей число в экспоненциальной форме

Проблема

Имеется строка, содержащая число в экспоненциальной форме, и требуется сохранить значение числа в переменной типа

double
.

Решение

Наиболее простым способом анализа числа в экспоненциальной форме является использование встроенного в библиотеку C++ класса

stringstream
, объявленного в
<sstream>
, как показано в примере 3.7.

Пример 3.7. Лексический анализ числа в экспоненциальной форме

#include <iostream>

#include <sstream>

#include <string>

using namespace std;

double sciToDub(const strings str) {

 stringstream ss(str);

 double d = 0;

 ss >> d;

 if (ss.fail) {

string s = "Невозможно отформатировать ";

s += str;

s += " как число!";

throw (s);

 }

 return (d);

}

int main {

 try {

cout << sciToDub("1.234e5") << endl;

cout << sciToDub("6.02e-2") << endl;

cout << sciToDub("asdf") << endl;

 } catch (string& e) {

cerr << "Ошибка: " << e << endl;

 }

}

Далее показан вывод этого кода.

123400

0.0602

Ошибка: невозможно отформатировать asd как число!

Обсуждение

Класс

stringstream
— это
string
, который ведет себя как поток (что неудивительно). Он объявлен в
<sstring>
. Если требуется выполнить анализ
string
, содержащей число в экспоненциальной форме (см. также рецепт 3.2), то с этой работой прекрасно справится
stringstream
. Стандартные классы потоков уже «знают», как анализировать числа, так что не тратьте без острой необходимости время на повторную реализацию этой логики.

В примере 3.7 я написал простую функцию

sciToDub
, принимающую параметр типа
string
и возвращающую содержащийся в ней
double
, если он допустим. В
sciToDub
я использую
stringstream
следующим образом.

stringstream ss(str); // Конструирование из строки типа string

double d = 0;

ss >> d;

if (ss.fail) {

 string s = "Невозможно отформатировать ";

 s += str;

 s += " как число!";

 throw (s);

}

return (d);

Наиболее важной частью здесь является то, что все, что требуется сделать, — это использовать для чтения из строкового потока в

double
оператор сдвига вправо (
>>
), как это делается при чтении из
cin
.

Ну, это не совсем все, что требуется сделать. Если в

stringstream
записано значение, которое не может быть записано в переменную в правой части оператора
>>
, то для потока будет выставлен бит
fail
. Этот бит можно проверить с помощью функции-члена
fail
(на самом деле это функция-член
basic_ios
, который является родительским классом для
stringstream
). Кроме того, переменная справа от оператора
>>
в случае ошибки значения не меняет.

Однако с целью обобщения можно избежать написания отдельных версий

sciToDub
для типов
int
,
float
,
double
и чего-либо еще, что может потребоваться преобразовать, если написать шаблон функции. Рассмотрим такую новую версию.

template<typename T>

T strToNum(const string& str) {

 stringstream ss(str);

 T tmp;

 ss >> tmp;

 if (ss.fail) {

  • Читать дальше
  • 1
  • ...
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • ...

Private-Bookers - русскоязычная библиотека для чтения онлайн. Здесь удобно открывать книги с телефона и ПК, возвращаться к сохраненной странице и держать любимые произведения под рукой. Материалы добавляются пользователями; если считаете, что ваши права нарушены, воспользуйтесь формой обратной связи.

Полезные ссылки

  • Моя полка