Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Lek11.doc
Скачиваний:
16
Добавлен:
15.11.2018
Размер:
139.78 Кб
Скачать

11.6. Преобразование строк с в числа

Строка С "1234" и число 1234 — это не одно и то же. Первое выражение представ­ляет собой последовательность символов, а второе — число. В жизни мы записы­ваем их одинаково и не думаем о различии, но в программе, созданной на языке C++, это различие нельзя игнорировать. Если вы собираетесь выполнять над чис­лом арифметические операции, вам требуется именно число, а не строка, то есть 1234, а не "1234". Если же вам нужно добавить запятую, чтобы отделить тысячи от сотен, тогда требуется строка "1234", которую можно превратить в "1.234". Когда программа должна вводить числа, часто удобнее считывать их как строки симво­лов, редактировать в таком виде и затем преобразовывать в числа. Скажем, если программа должна прочитать значение денежной суммы, пользователь может вве­сти перед ним символ доллара, а может и не вводить, а когда программа считывает процентное значение, можно поставить в конце знак процента, а можно и не ста­вить. Программе эти знаки не нужны. Поэтому она может прочитать введенное значение как строку символов, сохранить его в строковой переменной С и уда­лить ненужные символы, оставив только цифры. После этого строку нужно будет преобразовать в число, что очень легко выполнить с помощью стандартной функ­ции atoi.

Эта функция принимает один аргумент — строку С — и возвращает значение типа int, соответствующее представленному этой строкой числу. Так, atoi ("1234") воз­вращает число 1234. Если строка не содержит числа, функция возвращает 0. На­пример, ("#37") возвращает 0, поскольку значение аргумента ("#37") не является цифрой. Название этой функции представляет собой сокращение от англ. alphabe­tic to integer (произносится как «эй-ту-ай»). Функция atoi определена в библио­теке с заголовочным файлом <cstdlib>, так что любая программа, в которой она используется, должна содержать следующую директиву:

#include <cstdlib>

Если число слишком велико для преобразования его к типу данных int, можно преобразовать строку в значение типа long. Это выполняет функция atol, точно такая же, как atoi, и отличающаяся от нее лишь типом возвращаемого значения.

В листинге 14.1 приведено определение функции readandclean, считывающей введенную пользователем строку и удаляющей из нее все символы, кроме цифр от ' 0' до ' 9'. С помощью функции atoi она преобразует «очищенную» строку в це­лочисленное значение. Как показывает демонстрационная программа, функцию readandclean можно использовать для ввода значений денежных сумм независи­мо от того, добавит ли пользователь символ доллара. Точно так же с ее помощью можно вводить процентные значения независимо от наличия знака процента. По­смотрев на выходные данные, можно подумать, что функция просто удаляет из входной строки некоторые символы, но на самом деле она делает больше: форми­рует значение типа int, которым можно пользоваться в программе как числом, а не как строкой символов.

Листинг 11.1. Преобразование строки С в целое число

// Демонстрирует функцию read_and_clean.

#iinclude <iostream>

#include <cstdlib>

#include <cctype>

void read_and_clean(int& n);

// Считывает входную строку. Удаляет все символы, кроме цифр.

// Преобразует полученную строку С в число и записывает

// его в параметр n.

void new_line();

// Удаляет из входного потока все символы до конца текущей строки.

// Удаляет также символ '\n' в конце строки.

int main()

{

using namespace std;

int n;

char ans;

do

{

cout << "Enter an integer and press Enter: ";

read_and_clean(n);

cout << "That string converts to the integer " << n <<endl;

cout << "Again? (yes/no): ";

cin >> ans;

new_line(); }

while ( (ans != 'n') && (ans != 'N') );

return 0; }

// Используем библиотеки классов iostream, cstdlib и cctype.

void read_and_clean(int& n)

{

using namespace std;

const int ARRAY_SIZE = 6;

char digit_string[ARRAY_SIZE];

char next;

cin.get(next);

int index =0;

while (next != '\n')

{

if ( (isdigit(next)) && (index < ARRAY_SIZE - 1) )

{

digit_string[index] = next;

index++;

}

cin.get(next);

}

digit_string[index] = '\0';

n = atoi(digitstring);

}

// Используем библиотеку классов iostream.

void newline()

{

using namespace std:

char symbol;

do

{

cin.get(symbol);

}while(symbol!= '\n');

}

Пример диалога

Enter an integer and press Enter: $ 100

That string converts to the integer 100

Again? (yes/no): yes

Enter an integer and press Enter: 100

That string converts to the integer 100

Again? (yes/no): yes

Enter an integer and press Enter: 99*

That string converts to the integer 99

Again? (yes/no): yes

Enter an integer and pfess Enter: 23% &&5 *12

That string converts to the integer 23512

Again? (yes/no): no

Функция read_and_clean, приведенная в листинге 14.1, удаляет из введенной поль­зователем строки все нецифровые символы, но она не может проверить, соответ­ствует ли оставшаяся последовательность символов тому числу, которое хотел ввести пользователь. Нужно предоставить ему возможность посмотреть на ре­зультат преобразования и подтвердить, что все сделано правильно. Если получе­но неверное значение, пользователь должен иметь возможность повторить ввод. В листинге 14.2 функция read_and_clean вызывается из другой функции, называю­щейся get_int, которая принимает все данные, введенные пользователем, и позво­ляет ему повторять ввод, пока он не будет удовлетворен числом, полученным из введенной им строки. Это довольно надежная процедура ввода. Функции read_and_clean из листинга 14.1 и get_int из листинга 14.2 являются при­мерами пользовательских функций для ввода целых числовых значений. Есть и стандартная функция, преобразующая строковое значение в число типа double. Такая функция — atof и находится в той же библиотеке клас­сов с заголовочным файлом cstdlib. Например, функция atof("9.99") возвращает значение 9.99 типа double. Если строка не содержит число, которое можно интер­претировать как значение типа double, то данная функция возвращает 0.0. Назва­ние функции представляет собой сокращение от англ. alphabetic to floating point (произносится как «эй-ту-эф»). Вспомните, что числа с десятичной точкой часто называют числами с плавающей запятой из-за особого способа их хранения в па­мяти компьютера.

Преобразование строки С в число

Функции atoi, atol и atof можно использовать для преобразования строки С, состоя­щей из цифр, в числовое значение. Первые две функции преобразуют строку С в цело­численное значение. Единственная разница между ними заключается в том, что atoi возвращает значение типа int, a atol — значение типа long. Третья функция — atof — преобразует строку С в значение типа doublе. Если строка С, переданная в качестве ар­гумента любой из этих функций, не может быть преобразована в число, то функция возвращает 0. Например, оператор

int х = atoi("657");

присваивает переменной X значение 657, а оператор

double у = atof("12.37");

присваивает переменной у значение 12.37.

Любая программа, использующая функцию atoi, atol или atof, должна содержать сле­дующую директиву:

#include <cstdlib>

Листинг 11.2. Функция ввода с повышенной надежностью

#include <iostream>

#include <cstdlib>

#include <cctype>

void read_and_clean(int& n);

// Считывает входную строку. Удаляет все символы, кроме цифр. Преобразует

// результирующею строку С в число и записывает его в параметр п.

void newline();

// Удаляет из входного потока все символы до конца текущей строки.

// Удаляет также символ '\n' в конце строки.

void get_int(int& inputnumber);

// Присваивает параметру inputnumber число, правильность которого

// подтвердит пользователь.

int main()

{

using namespace std;

int inputnumber;

get_int(inputnumber);

cout <<"Final value read in = " <<input_number <<endl;

return 0; }

// Используем библиотеку классов iostream и функцию read_and_clean.

void get_int(int& inputnumber)

{

using namespace std;

char ans;

do

{

cout << "Enter input number: ";

read_and_clean(inputnumber);

cout << "You entered " << inputnumber << " Is that correct? (yes/no): ";

cin » ans;

newline(); }

while ((ans != 'y') && (ans != 'Y')); }

// Используем библиотеки классов iostream, cstdlib и cctype.

void read_and_clean(int& n)

{

... Определение функции read_and_clean приведено в листинге 14.1.

}

// Используем библиотеку классов iostream.

void newline()

{

... Определение функции newline приведено в листинге 14.1. ...

}

Пример диалога

Enter input number: $57

You entered 57 Is that correct? (yes/no): no

Enter input number: $77*5xa

You entered 775 Is that correct? (yes/no): no

Enter input number: 77

You entered 77 Is that correct? (yes/no): no

Enter input number: $75

You entered 75 Is that correct? (yes/no): yes

Final value read in = 75

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]