Студопедия

Главная страница Случайная страница

КАТЕГОРИИ:

АвтомобилиАстрономияБиологияГеографияДом и садДругие языкиДругоеИнформатикаИсторияКультураЛитератураЛогикаМатематикаМедицинаМеталлургияМеханикаОбразованиеОхрана трудаПедагогикаПолитикаПравоПсихологияРелигияРиторикаСоциологияСпортСтроительствоТехнологияТуризмФизикаФилософияФинансыХимияЧерчениеЭкологияЭкономикаЭлектроника






Листинг 16.20. Использование аргументов командной строки






1: #include < fstream.h>

2:

3: class Animal

4: {

5: public:

6: Animal(intweight, long days): itsWeight(weight), itsNumberDaysAlive(days)(}

7: ~Animal(){ }

8:

9: int GetWeight()const { return itsWeight; }

10: void SetWeight(int weight) { itsWeight = weight; }

11:

12: long GetDaysAlive()const { return itsNumberDaysAlive; }

13: void SetDaysAlive(long days) { itsNumberDaysAlive = days; }

14:

15: private:

16: int itsWeight;

17: long itsNumberDaysAlive;

18: };

19:

20: int main(int argc, char *argv[]) // возвращает 1 в случае ошибки

21: {

22: if (argc! = 2)

23: {

24: cout < < " Usage: " < < argv[0] < < " < filename> " < < endl;

25: return(1);

26: }

27:

28: ofstream fout(argv[1], ios:: binary);

29: if (! fout)

30: {

31: cout < < " Unable to open " < < argv[1] < < " for writing.\n";

32: return(1);

33: }

34:

35: Animal Bear(50, 100);

36: fout.write((char*) & Bear, sizeof Bear);

37:

38: fout.close();

39:

40: ifstream fin(argv[1], ios:: binary);

41: if (! fin)

42: {

43: cout < < " Unable to open " < < argv[1] < < " for reading.\n";

44: return(1);

45: }

46:

47: Animal BearTwo(1, 1);

48:

49: cout < < " BearTwo weight: " < < BearTwo.GetWeight() < < endl;

50: cout < < " BearTwo days: " < < BearTwo.GetDaysAlive() < < endl;

51:

52: fin.read((char*) & BearTwo, sizeof BearTwo);

53:

54: cout < < " BearTwo weight: " < < BearTwo.GetWeight() < < endl;

55: cout < < " BearTwo days: " < < BearTwo.GetDaysAlive() < < endl;

56: fin.close();

57: return 0;

58: }

 

Результат:

BearTwo weight: 1

BearTwo days: 1

BearTwo weight: 50

BearTwo days: 100

 

Анализ: Объявление класса Animal аналогично представленному в листинге 16.18. Однако в этом случае пользователю не предлагается ввести имя файла, а используется аргумент командной строки. В строке 2 объявляется функция main(), принимающая два параметра: количество аргументов командной строки и указатель на массив символов, в котором сохраняются аргументы командной строки.

В строках 22—26 проверяется, соответствует ли установленное число аргументов ожидаемому. Если пользователь забыл ввести имя файла, то выводится сообщение об ошибке:

Usage TestProgram < имя файла>

После этого программа завершает свою работу. Обратите внимание, что при выводе имени программы используется не константная строка, а значение argv[0]. Данное выражение будет правильно выводить имя программы, даже если оно будет изменено после компиляции.

В строке 28 программа пытается открыть двоичный файл с указанным именем. Однако, вместо того чтобы копировать и хранить имя файла во временном массиве, как это было в листинге 16.18, его можно задать в командной строке и затем возвратить из argv[1 ].

Точно так же имя файла возвращается в строке 40, где этот файл открывается для ввода данных, и в строках 25 и 31 при формировании сообщений об ошибках открытия файлов.

 

 

Резюме

 

Сегодня вы познакомились с потоками и глобальными объектами cout и cin. Основное предназначение объектов istream и ostream состоит в инкапсулировании буферизированого ввода и вывода данных на стандартные устройства ввода-вывода.

В каждой программе создается четыре стандартных потоковых объекта: cout, cin, cerr и clog. Однако в большинстве операционных систем эти объекты можно переадресовывать.

Объект cin класса istream используется для ввода данных обычно вместе с перегружаемым оператором ввода (> >). Объект cout класса ostream используется для вывода данных в комбинации с оператором вывода (< <).

Стандартные объекты ввода-вывода включают много других функций-членов, например get() и put(). Поскольку эти методы возвращают ссылки на объект потока, несколько вызовов функций можно объединять в одном выражении.

Для настройки работы объектов потока используются манипуляторы. С их помощью можно устанавливать не только опции форматирования и отображения, но и многие другие атрибуты объектов потока.

Обмен данными с файлами осуществляется с помощью классов fstream, производных от класса iostream. Кроме обычных операторов ввода и вывода, эти классы поддерживают использование функций read() и write(), позволяющих считывать и записывать целые объекты в двоичные файлы.

 

Вопросы и ответы

 

Как определить, когда использовать операторы ввода и вывода, а когда другие функции-члены классов потока?

В целом операторы ввода и вывода проще в использовании, поэтому в большинстве случаев лучше обращаться именно к ним. В некоторых других случаях, когда эти операторы не справляются со своей работой (например, при вводе строки из слов, разделенных пробелами), можно прибегнуть к использованию других функций.

Какое отличие между cerr и clog?

Объект cerr не буферизируется? Другими словами, все данные, поступающие в cerr, немедленно выводятся на экран. Это отлично подходит для вывода ошибок на

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

Зачем создавать потоки, если отлично работает функция printf()? Функция printf() не контролирует строго типы выводимых данных, чего требуют стандарты C++. Кроме того, эта функция не поддреживает работу с классами.

Когда следует применять метод putback()?

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

Когда следует использовать функцию ignore()?

Наиболее часто она используется после функции get(). Поскольку последняя оставляет в буфере символ разрыва строки, иногда за вызовом функции get() следует вызов ignore(1, '\n');. Эта функция, как и putback(), используется, как правило, при синтаксическом разборе файлов.

Мои друзья используют в своих программах на C++ функцию printf(). Можно ли и мне ее использовать?

Конечно же, можно. Однако, хотя эта функция более проста в использовании, вы утратите строгий контроль за типами файлов и затрудните работу с объектами классов.

 


Поделиться с друзьями:

mylektsii.su - Мои Лекции - 2015-2024 год. (0.011 сек.)Все материалы представленные на сайте исключительно с целью ознакомления читателями и не преследуют коммерческих целей или нарушение авторских прав Пожаловаться на материал