Чтение онлайн

на главную

Жанры

Программирование. Принципы и практика использования C++ Исправленное издание
Шрифт:

Функция

scanf
считывает данные с помощью формата точно так же, как и функция
printf
. Как и функция
printf
, она может быть очень удобной.

void f

{

int i;

char c;

double d;

char* s = (char*)malloc(100);

/* считываем данные в переменные, передаваемые как указатели: */

scanf("%i %c %g %s", &i, &c, &d, s);

/*
спецификатор %s пропускает первый пробел и прекращает

действие на следующем пробеле */

}

Как и функция
printf
, функция
scanf
не является безопасной с точки зрения типов. Форматные символы и аргументы (все указатели) должны точно соответствовать друг другу, иначе во время выполнения программы будут происходить странные вещи. Обратите также внимание на то, что считывание данных в строку
s
с помощью спецификатора
%s
может привести к переполнению. Никогда не используйте вызовы
gets
или
scanf("%s")
!

Итак, как же безопасно ввести символы? Мы можем использовать вид формата %s, устанавливающий предел количества считываемых символов. Рассмотрим пример.

char buf[20];

scanf("%19s",buf);

Нам требуется участок памяти, заканчивающийся нулем (содержание которого вводится функцией

scanf
), поэтому 19 — это максимальное количество символов, которое можно считать в массив
buf
. Однако этот способ не отвечает на вопрос, что делать, если некто введет больше 19 символов. Лишние символы останутся в потоке ввода и будут обнаружены при следующей попытке ввода.

Проблема с функцией

scanf
означает, что часто благоразумно и легче использовать функцию
getchar
. Типичный ввод символов с помощью функции
getchar
выглядит следующим образом:

while((x=getchar)!=EOF) {

/* ... */

}

Макрос

EOF
, описанный в библиотеке
stdio
, означает “конец файла”; см. также раздел 27.4.

Альтернативы функций

scanf("%s")
и
gets
в стандартной библиотеке языка C++ от этих проблем не страдают.

string s;

cin >> s; // считываем слово

getline(cin,s); // считываем строку

27.6.3. Файлы

В языке C (и C++) файлы можно открыть с помощью функции

fopen
, а закрыть — с помощью функции
fclose
. Эти функции, вместе с представлением дескриптора файлов
FILE
и макросом
EOF
(конец файла), описаны в заголовочном файле
<stdio.h>
.

FILE *fopen(const char* filename, const char* mode);

int fclose(FILE *stream);

По

существу, мы используем файлы примерно так:

void f(const char* fn, const char* fn2)

{

FILE* fi = fopen(fn, "r"); /* открываем файл fn для чтения */

FILE* fo = fopen(fn2, "w"); /* открываем файл fn для записи */

if (fi == 0) error("невозможно открыть файл для ввода");

if (fo == 0) error("невозможно открыть файл для вывода");

/* чтение из файла с помощью функций ввода из библиотеки stdio,

например, getc */

/* запись в файл с помощью функций вывода из библиотеки stdio,

например, fprintf */

fclose(fo);

fclose(fi);

}

Учтите: в языке С нет исключений, потому вы не можете узнать, что при обнаружении ошибок файлы были закрыты.

27.7. Константы и макросы

В языке С константы не являются статическими.

const int max = 30;

const int x; /* неинициализированная константа: OK в C

(ошибка в C++) */

void f(int v)

{

int a1[max]; /* ошибка: граница массива не является константой

(OK в языке C++) */

/* (слово max не допускается в константном

выражении!) */

int a2[x]; /* ошибка: граница массива не является константой */

switch (v) {

case 1:

/* ... */

break;

case max: /* ошибка: метка раздела case не является

константой
(OK в языке C++) */

/* ... */

break;

}

}

По техническим причинам в языке С (но не в языке C++) неявно допускается, чтобы константы появлялись из других модулей компиляции.

/* файл x.c: */

const int x; /* инициализирована в другом месте */

/* файл xx.c: */

const int x = 7; /* настоящее определение */

В языке С++ в разных файлах могут существовать два разных объекта с одним и тем же именем

x
. Вместо использования ключевого слова
const
для представления символьных констант программисты на языке С обычно используют макросы. Рассмотрим пример.

Поделиться:
Популярные книги

Конструктор

Семин Никита
1. Переломный век
Фантастика:
попаданцы
альтернативная история
4.50
рейтинг книги
Конструктор

Афганский рубеж

Дорин Михаил
1. Рубеж
Фантастика:
попаданцы
альтернативная история
7.50
рейтинг книги
Афганский рубеж

Колючка для высшего эльфа или сиротка в академии

Жарова Анита
Любовные романы:
любовно-фантастические романы
5.00
рейтинг книги
Колючка для высшего эльфа или сиротка в академии

Имперец. Том 4

Романов Михаил Яковлевич
3. Имперец
Фантастика:
попаданцы
альтернативная история
аниме
5.00
рейтинг книги
Имперец. Том 4

Совок 2

Агарев Вадим
2. Совок
Фантастика:
альтернативная история
7.61
рейтинг книги
Совок 2

Кровь и Пламя

Михайлов Дем Алексеевич
7. Изгой
Фантастика:
фэнтези
8.95
рейтинг книги
Кровь и Пламя

Третий

INDIGO
Фантастика:
космическая фантастика
попаданцы
5.00
рейтинг книги
Третий

Внешняя Зона

Жгулёв Пётр Николаевич
8. Real-Rpg
Фантастика:
фэнтези
попаданцы
рпг
5.00
рейтинг книги
Внешняя Зона

Приручитель женщин-монстров. Том 1

Дорничев Дмитрий
1. Покемоны? Какие покемоны?
Фантастика:
юмористическое фэнтези
аниме
5.00
рейтинг книги
Приручитель женщин-монстров. Том 1

Камень

Минин Станислав
1. Камень
Фантастика:
боевая фантастика
6.80
рейтинг книги
Камень

Шесть тайных свиданий мисс Недотроги

Суббота Светлана
Любовные романы:
любовно-фантастические романы
эро литература
7.75
рейтинг книги
Шесть тайных свиданий мисс Недотроги

Измена. Мой непрощённый

Соль Мари
2. Самойловы
Любовные романы:
современные любовные романы
5.00
рейтинг книги
Измена. Мой непрощённый

Внешники

Кожевников Павел
Вселенная S-T-I-K-S
Фантастика:
боевая фантастика
попаданцы
5.00
рейтинг книги
Внешники

Зауряд-врач

Дроздов Анатолий Федорович
1. Зауряд-врач
Фантастика:
альтернативная история
8.64
рейтинг книги
Зауряд-врач