Как сделать чтобы не писать каждый раз std

Добавил пользователь Алексей Ф.
Обновлено: 05.10.2024

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

Это выглядит примерно так :

информация о файле:

после оценки после исправления: файл выглядит так:

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

у кого-нибудь есть идея, как я могу этого добиться?

Трудно сказать, что вы делаете неправильно, если мы не знаем, что вы делаете, поэтому я настоятельно рекомендую добавить минимальный воспроизводимый пример, который покрывает вашу запись вывода.

только что отредактировал вопрос, я был бы признателен, если бы вы увидели, чего я пытаюсь достичь

Ответы 2

Я предполагаю, что в вашем коде не будет скобок, и все числа будут положительными целыми числами, разделенными операторами или пробелами.

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

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

Повторяйте, пока не прочитаете оператор (+, -, *, /)

Когда вы прочитаете оператор, примените этот оператор к двум последним значениям в стеке и поместите результат в стек.

Вот как математика выполняется внутри компиляторов.

После того, как вы завершили строку, проверьте, есть ли в стеке только одно значение. Если нет, значит, в инструкциях есть несовпадающее количество целых чисел и операторов. Если есть только один номер, запишите его в файл.

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

Затем прочитайте каждую строку из входного файла и вставьте ее вместе с результатом в выходной файл.

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

@T.Matar Я обновил свой ответ.

Единственное, что в этом ответе даже отдаленно касается заданного вопроса, - это самые последние 2 предложения. Прочитайте строку из входного файла, обработайте ее по мере необходимости, запишите ее и ее результат в другой выходной файл и повторяйте до тех пор, пока строки не будут прочитаны. Остальное не имеет значения и должно быть удалено.

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

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

В этом уроке мы подробно рассмотрим способы, которыми пользователь может вводить недопустимые текстовые данные через std::cin , и покажем вам несколько разных способов обработки таких случаев.

std::cin , буферы и извлечение

Чтобы обсудить, как std::cin и operator>> могут давать сбой, сначала полезно немного узнать, как они работают.

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

При использовании оператора извлечения происходит следующая процедура:

  • Если во входном буфере уже есть данные, то для извлечения используются они.
  • Если входной буфер не содержит данных, пользователя просят ввести данные для извлечения (так бывает в большинстве случаев). Когда пользователь нажимает Enter , во входной буфер помещается символ '\n' .
  • operator>> извлекает столько данных из входного буфера, сколько может, в переменную (игнорируя любые начальные пробельные символы, такие как пробелы, табуляции или '\n' ).
  • Любые данные, которые не могут быть извлечены, остаются во входном буфере для следующего извлечения.

Извлечение завершается успешно, если из входного буфера извлечен хотя бы один символ. Любые неизвлеченные входные данные остаются во входном буфере для дальнейшего извлечения. Например:

Если пользователь вводит "5a" , 5 будет извлечено, преобразовано в целое число и присвоено переменной x . А "a\n" останется во входном потоке для следующего извлечения.

Извлечение не выполняется, если входные данные не соответствуют типу переменной, в которую они извлекаются. Например:

Если бы пользователь ввел 'b' , извлечение не удалось бы, потому что 'b' не может быть извлечено в переменную типа int .

Проверка ввода

Процесс проверки того, соответствуют ли пользовательские входные данные тому, что ожидает программа, называется проверкой ввода.

Есть три основных способа проверки ввода:

  • встроенный (по мере печати пользователя):
    • прежде всего, не позволить пользователю вводить недопустимые данные;
    • позволить пользователю ввести в строку всё, что он хочет, затем проверить правильность строки и, если она корректна, преобразовать строку в окончательный формат переменной;
    • позволить пользователю вводить всё, что он хочет, позволить std::cin и operator>> попытаться извлечь данные и обработать случаи ошибок.

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

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

    Пример программы

    Рассмотрим следующую программу-калькулятор, в которой нет обработки ошибок:

    Эта простая программа просит пользователя ввести два числа и математический оператор.

    Теперь подумайте, где неверный ввод пользователя может нарушить работу этой программы.

    Сначала мы просим пользователя ввести несколько чисел. Что, если он введет что-то, отличающееся от числа (например, 'q' )? В этом случае извлечение не удастся.

    Во-вторых, мы просим пользователя ввести один из четырех возможных символов. Что, если он введет символ, отличный от ожидаемых? Мы сможем извлечь входные данные, но пока не обрабатываем то, что происходит после.

    В-третьих, что, если мы попросим пользователя ввести символ, а он введет строку типа "*q hello" . Хотя мы можем извлечь нужный нам символ '*' , в буфере останутся дополнительные входные данные, которые могут вызвать проблемы в будущем.

    Типы недопустимых входных текстовых данных

    Обычно мы можем разделить ошибки ввода текста на четыре типа:

    1. извлечение входных данных выполняется успешно, но входные данные не имеют смысла для программы (например, ввод 'k' в качестве математического оператора);
    2. извлечение входных данных выполняется успешно, но пользователь вводит дополнительные данные (например, вводя "*q hello" в качестве математического оператора);
    3. ошибка извлечения входных данных (например, попытка ввести 'q' при запросе ввода числа);
    4. извлечение входных данных выполнено успешно, но пользователь выходит за пределы значения числа.

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

    Давайте разберемся в каждом из этих случаев и в том, как их обрабатывать с помощью std::cin .

    Случай ошибки 1: извлечение успешно, но входные данные не имеют смысла

    Это самый простой случай. Рассмотрим следующий вариант выполнения приведенной выше программы:

    В этом случае мы попросили пользователя ввести один из четырех символов, но вместо этого он ввел 'k' . 'k' – допустимый символ, поэтому std::cin успешно извлекает его в переменную op , и она возвращается в main . Но наша программа не ожидала этого, поэтому она не обрабатывает этот случай правильно (и, таким образом, ничего не выводит).

    Решение здесь простое: выполните проверку ввода. Обычно она состоит из 3 шагов:

    1. убедитесь, что пользовательский ввод соответствует вашим ожиданиям;
    2. если да, верните значение вызывающей функции;
    3. если нет, сообщите пользователю, что что-то пошло не так, и попросите его повторить попытку.

    Вот обновленная функция getOperator() , которая выполняет проверку ввода.

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

    Случай ошибки 2: извлечение успешно, но с посторонними входными данными

    Рассмотрим следующий вариант выполнения приведенной выше программы:

    Как думаете, что будет дальше?

    Программа выводит правильный ответ, но форматирование испорчено. Давайте подробнее разберемся, почему.

    Когда пользователь вводит "5*7" в качестве вводных данных, эти данные попадают в буфер. Затем оператор >> извлекает 5 в переменную x , оставляя в буфере "*7\n" . Затем программа напечатает "Enter one of the following: +, -, *, or /:" . Однако когда был вызван оператор извлечения, он видит символы "*7\n" , ожидающие извлечения в буфере, поэтому он использует их вместо того, чтобы запрашивать у пользователя дополнительные данные. Следовательно, он извлекает символ '*' , оставляя в буфере "7\n" .

    После запроса пользователя ввести другое значение double , из буфера извлекается 7 без ожидания ввода пользователя. Поскольку у пользователя не было возможности ввести дополнительные данные и нажать Enter (добавляя символ новой строки), все запросы в выводе идут вместе в одной строке, даже если вывод правильный.

    Хотя программа работает, выполнение запутано. Было бы лучше, если бы любые введенные посторонние символы просто игнорировались. К счастью, символы игнорировать легко:

    Этот вызов удалит до 100 символов, но если пользователь ввел более 100 символов, мы снова получим беспорядочный вывод. Чтобы игнорировать все символы до следующего символа '\n' , мы можем передать std::numeric_limits ::max() в std::cin.ignore() . std::numeric_limits ::max() возвращает наибольшее значение, которое может быть сохранено в переменной типа std::streamsize . Передача этого значения в std::cin.ignore() приводит к отключению проверки счетчика.

    Чтобы игнорировать всё, вплоть до следующего символа '\n' , мы вызываем

    Поскольку эта строка довольно длинная для того, что она делает, будет удобнее обернуть ее в функцию, которую можно вызвать вместо std::cin.ignore() .

    Поскольку последний введенный пользователем символ должен быть '\n' , мы можем указать std::cin игнорировать символы в буфере, пока не найдет символ новой строки (который также будет удален).

    Давайте обновим нашу функцию getDouble() , чтобы игнорировать любой посторонний ввод:

    Теперь наша программа будет работать, как ожидалось, даже если мы введем "5*7" при первом запросе ввода – 5 будет извлечено, а остальные символы из входного буфера будут удалены. Поскольку входной буфер теперь пуст, при следующем выполнении операции извлечения данные у пользователя будут запрашиваться правильно!

    Случай ошибки 3: сбой при извлечении

    Теперь рассмотрим следующий вариант выполнения нашей программы калькулятора:

    Неудивительно, что программа работает не так, как ожидалось, но интересно, как она дает сбой:

    и программа внезапно завершается.

    Это очень похоже на случай ввода посторонних символов, но немного отличается. Давайте посмотрим подробнее.

    Давайте, интегрируем это в нашу функцию getDouble() :

    Примечание. До C++11 неудачное извлечение не приводило к изменению извлекаемой переменной. Это означает, что если переменная была неинициализирована, она останется неинициализированной в случае неудачного извлечения. Однако, начиная с C++11, неудачное извлечение из-за недопустимого ввода приведет к тому, что переменная будет инициализирована нулем. Инициализация нулем означает, что для переменной установлено значение 0, 0.0, "" или любое другое значение, в которое 0 преобразуется для этого типа.

    Случай ошибки 4: извлечение успешно, но пользователь выходит за пределы значения числа

    Рассмотрим следующий простой пример:

    Что произойдет, если пользователь введет слишком большое число (например, 40000)?

    Примечание. До C++11 неудачное извлечение не приводило к изменению извлекаемой переменной. Это означает, что если переменная была неинициализирована, в случае неудачного извлечения она останется неинициализированной. Однако, начиная с C++11, неудачное извлечение вне диапазона приведет к тому, что переменной будет присвоено ближайшее значение в диапазоне.

    Собираем всё вместе

    Вот наш пример калькулятора с полной проверкой ошибок:

    Заключение

    При написании программы подумайте о том, как пользователи будут неправильно использовать вашу программу, особенно при вводе текста. Для каждой точки ввода текста учтите:

    • Могло ли извлечение закончиться неудачей?
    • Может ли пользователь ввести больше, чем ожидалось?
    • Может ли пользователь ввести бессмысленные входные данные?
    • Может ли пользователь переполнить входные данные?

    Вы можете использовать операторы if и булеву логику, чтобы проверить, являются ли входные данные ожидаемыми и осмысленными.

    Следующий код очистит любые посторонние входные данные:

    Следующий код будет проверять и исправлять неудачные извлечения или переполнение:

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

    Примечание автора

    Проверка ввода важна и полезна, но она также делает примеры более сложными и трудными для понимания. Соответственно, на будущих уроках мы, как правило, не будем проводить никакой проверки вводимых данных, если они не имеют отношения к чему-то, чему мы пытаемся научить.

    В языке программирования C++ термин Стандартная Библиотека (далее – STD ) означает коллекцию классов и функций для решения различных задач. STD и ядро языка C++ развивались и стандартизировались параллельно. В следствие этого, многие важные вещи, например ввод/вывод, не являются частью ядра, а принадлежат STD. Все компоненты STD согласованы друг с другом, но основаны на разных принципах проектирования. В основу разработки библиотеки положена парадигма обобщенного программирования. Все классы библиотеки – это шаблоны. Средства стандартной библиотеки объявляются как входящие в пространство имён std . Стандартная библиотека С++ включает в себя часть стандартной библиотеки языка C. Стандарт C++17 содержит нормативную ссылку на стандарт C11 и не определяет самостоятельно те функции стандартной библиотеки, которые заимствуются из стандартной библиотеки C.
    Доступ к возможностям STD C++ обеспечивается с помощью включения в программу соответствующих стандартных заголовочных файлов. Всего в стандарте C++20 определено 108 таких файлов. STD содержит следующие разделы:

    • Concepts library
    • Coroutines library
    • Utilities library
    • Dynamic memory management
    • Numeric limits
    • Error handling
    • Strings library
    • Containers library
    • Iterators library
    • Ranges library
    • Algorithms library
    • Numerics library
    • Input/output library
    • Localization library
    • Regular Expressions library
    • Atomic Operations library
    • Thread support library
    • Filesystem library

    Заметим, что компиляторы не поддерживают на 100% компоненты STD последних стандартов. Если говорить о GCC, то разработчики включают некоторые возможности STD до выхода стандарта, а некоторые заявленные в текущем стандарте вещи остаются не реализованными. Например, тип char8_t поддерживается с 9 версии GCC, т. е. раньше, чем вышел стандарт в котором он был заявлен (C++20). Или Concepts library уже обрела поддержку в GCC-10, но не реализована в компиляторе Clang (на начало лета 2020 г.). Modules (входящие в библиотеку утилит) в GCC не реализованы, но частично поддерживаются Clang и т. д. Получить более детальные сведения о поддержке стандартов C++ в GCC можно на этих сайтах: C++ Standards Support in GCC и C++ compiler support. Поэтому, прежде чем включать тот или иной компонент STD в свою программу, убедитесь о его поддержке используемым компилятором. В данном курсе используются только поддерживаемые компоненты в компиляторе GCC 10 стандарта C++17.
    Каждый заголовочный файл из стандартной библиотеки языка Си включен в STD C++ под именами, начинающиеся префиксом 'c' , например, ctime , .
    По правилам языка C++ соответствующий компонент STD добавляется в программу путем включения заголовочного файла с помощью директивы:

    при этом обычное “расширение” в имени заголовочных файлов ( ".h" ) отбрасывается.

    Ранее мы уже акцентировали ваше внимание на том, что полной совместимости между языками C и C++ не существует. В современном стандарте языка C++ появилось много вещей, которые не будут работать в языке Си, равно как и многие вещи принятые в Си перестали работать в С++. Например:

    В языке Си не существуют классы динамических контейнеров, которые освобождают память в автоматическом режиме. Динамические массивы в Си нужно создавать “вручную” с помощью библиотечных функций malloc , free и realloc . (В C++ поддерживаются функции работы с памятью из стандартной библиотеки Си, но их использование не рекомендуется). В продолжении нашего курса мы практически не обращаемся к библиотеке языка Си (за исключением cmath и ctime ).

    Компоненты STL

    Контейнеры, строки, алгоритмы, итераторы и основные утилиты, за исключением заимствований из библиотеки C, собирательно называются STL (Standard Template Library — стандартная шаблонная библиотека). STL, до включения в стандарт C++, была сторонней разработкой, в начале — фирмы HP, а затем SGI. Стандарт языка не называет её STL, так как эта библиотека стала неотъемлемой частью языка (и, следовательно, STD). Но в некоторых источниках до сих пор фигурирует эта аббревиатура, чтобы отличать STL от остальной части STD, подчеркивая, её некую обособленность и независимость. Но это не соответствует действительности и выглядит чересчур архаично. Обобщенная парадигма распространилась и на остальные части STD, первоначально не входившие в STL. Архитектуру STL разработали Александр Степанов и Менг Ли. STL вошла в стандартную библиотеку C++ весной 1994 года. В названии “STL” отражено то, что для реализации средств общего вида (контейнеров, строк, алгоритмов) использованы механизмы обобщённого программирования.
    В целом, STL состоит из двух основных частей: классы контейнеров и алгоритмы для работы с элементами контейнеров. Все компоненты STL являются шаблонами, поэтому их можно использовать для произвольных типов элементов, включая абстрактные. Со многими компонентами STL мы уже смогли познакомиться и научиться ими использовать при решении различных задач. Ниже приводятся ссылки на внутренние ресурсы сайта, где проводится детальный разбор соответствующего компонента.

    В STL выделяют пять основных компонентов:

    Контейнеры

    Обобщим наши знания о контейнерах. Контейнеры — это специализированные классы, предназначенные для хранения коллекции однотипных объектов и обеспечения доступа к этим объектам. Контейнер – это структура данных похожая на массив. Контейнер управляет выделяемой для его элементов памятью и предоставляет функции-члены для доступа к ним, либо непосредственно, либо через итераторы. Конструкторы контейнеров имеют дополнительный специальный аргумент allocator (распределитель). Аллокатор инкапсулирует (т. е. скрывает) реализацию выделения и освобождения памяти. Аллокатором по умолчанию является шаблон std::allocator (если не определен пользовательский распределитель). В качестве инструментов выделения и освобождения памяти этот аллокатор использует стандартные операции new и delete . Для различных контейнеров имеются как общие, так и специфичные операции, применимые только для данного вида коллекции объектов. Разные контейнеры обеспечивают различную эффективность тех или иных операций. Выбор оптимального контейнера для конкретного случая зависит не только от предоставляемой функциональности, но и от его эффективности при различных рабочих нагрузках. Контейнеры подразделяются на следующие виды:

    Последовательные контейнеры

    В последовательных контейнерах элементы располагаются последовательно, один за другим. Позиция зависит от времени и места вставки, но не связана со значением элемента. Каждый элемент контейнера имеет свой индекс (за исключением контейнера list ); как и в массивах, отсчет начинается с "0" . Но, в отличие от C-массивов, имеющих фиксированный размер, последовательные контейнеры – динамические массивы (за исключением контейнера array ). К последовательным контейнерам относятся классы:

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

    Ассоциативные контейнеры

    Ассоциативные контейнеры реализуют упорядоченные структуры данных с возможностью быстрого поиска. Достигается это автоматической сортировкой элементов (по умолчанию – по возрастанию) и принципиально иным способом внутреннего представления данных, основанного на сбалансированном бинарном дереве. К ассоциативным контейнерам относятся:

    Класс set (множество) представляет собой упорядоченный контейнер, соответствующий математическому понятию множества. set хранит упорядоченное множество уникальных ключей (или просто – значений).
    Класс map (словарь) реализует упорядоченный ассоциативный массив пар элементов, состоящих из уникальных ключей и соответствующих им значений. Контейнеры multiset и multimap допускают существование нескольких ключей с одинаковым значением.
    Помимо упорядоченных ассоциативных контейнеров, имеются неупорядоченные структуры данных (хеш-массивы) с возможностью быстрого поиска:

    • unordered_set
    • unordered_map
    • unordered_multiset
    • unordered_multimap
    Контейнеры-адаптеры

    Контейнеры-адаптеры (container adaptor) — это обёртки над другими контейнерами, предоставляющие особые наборы операций. Оборачиваемый контейнер может быть задан как дополнительный параметр шаблона. Если параметр не задан, будет использоваться, специфический для адаптера, контейнер по умолчанию. К контейнерам-адаптерам относятся:

    Псевдо-контейнеры

    Подведем черту упоминанием еще одного типа контейнеров – псевдо-контейнеров. Это особый вид контейнеров, которые созданы для специфичных элементов на основе каркаса для проектирования новых контейнеров, предоставляемого библиотекой стандартных шаблонов. К псевдо-контейнерам относятся:

    Независимые библиотеки для C++

    Помимо STD, различными компаниями разрабатываются и сторонние библиотеки. Многие из них приобрели большую популярность и активно используются разработчиками ПО. Среди них можно выделить следующие:

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

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

    Как начать

    Код можно писать в окне справа. Если вы не хотите программировать на сайте, то можете открыть среду программирования, в которой вы планируете писать на С++. Самая удобная программа для Windows, это Microsoft Visual Studio. Год издания на ваш выбор. На данный момент Microsoft сделали версию 2010 года бесплатной. Если вы пользуетесь Linux, то используйте любой текстовый редактор и GCC – это набор компиляторов, предназначенных для работы с С/С++.

    Создание в Visual Studio

    Начинаем писать код

    Теперь начнем писать код. Для начала перепишите код программы, который представлен ниже. Не стоит копировать, иначе уровень познания материала будет намного меньше, чем если вы перепишите своими руками пример. Пишите все точно так, как и в примере, соблюдая регистр и не забывая точки с запятой, пробелы и т.д. Если у вас программа не заработает, то просто скопируйте ее из примера.

    То, что вы сейчас написали, называется исходным кодом – это то, что человек может понять.

    Разбираем код по строкам

    Первая строка и 2-4 это комментарии. Комментарий, который начинается с двух косых черточек – это однострочные комментарии. Комментарии созданы для людей, компилятор их просто игнорирует и все. Многострочный комментарий начинается с косой черты и звездочки ( /* ), а заканчивается ( */ ).

    После подключения библиотек идет строка using namespace std , которая нужна для объявления пространства имен. То есть, чтобы не писать каждый раз: std::cin и std::cout , а писать cin и cout , а это намного удобнее и компактнее.

    Далее идет тело программы int main() <> , то есть все что внутри фигурных скобок будет выполняться после пуска программы.

    Запускаем программу

    Популярные вопросы

    1. Вопрос. Какой командой лучше останавливать экран: pause("system” ) или getch() . В чем разница между ними (если программировать в Visual Studio)?

    Большинство программ, имеющих хоть какой-либо пользовательский интерфейс, сталкиваются с обработкой пользовательского ввода. В программах, которые мы писали раньше, используется std::cin для получения пользовательского ввода. А так как ввод данных имеет свободную форму (пользователь может ввести всё, что пожелает), то пользователю очень легко ввести данные, которые от него никак не ожидаются.

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

    На этом уроке мы рассмотрим, как пользователи могут вводить некорректные данные через std::cin, а также как с этим бороться.

    std::cin, буфер данных и извлечение

    Прежде чем разбираться с обработкой некорректного ввода через std::cin и оператор >> , давайте сначала рассмотрим их принцип работы.

    Процесс, когда мы используем оператор >> для получения данных от пользователя и размещение этих данных в определенной переменной, называется извлечением. Соответственно, оператор >> называется оператором извлечения.

    Когда пользователь вводит данные в ответ на операцию извлечения, то эти данные помещаются в буфер std::cin. Буфер данных — это просто часть памяти, зарезервированная для временного хранения данных, когда они перемещаются из одного места в другое. В этом случае буфер используется для хранения пользовательского ввода, пока он находится в режиме ожидания выделения для него переменных.

    При использовании оператора извлечения, выполняется следующая процедура:

    Если во входном буфере есть данные, то эти данные используются для извлечения.

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

    Оператор >> извлекает столько данных из входного буфера в переменную, сколько позволяет размер самой переменной (игнорируя любые пробелы, табы или \n ).

    Любые данные, которые не были извлечены, остаются во входном буфере для последующего извлечения.

    Извлечение данных считается успешным, если по крайней мере один символ был извлечен из входного буфера. Оставшиеся данные во входном буфере используются для последующих извлечений. Например:

    Если пользователь введет 7d , то 7 будет извлечено, преобразовано в целое число и присвоено переменной a . А d\n останется во входном буфере дожидаться следующего извлечения.

    Извлечение не выполняется, если данные ввода не соответствуют типу переменной, выделенной для них. Например:

    Если бы пользователь ввел z , то извлечение не выполнилось бы, так как z не может быть извлечено в целочисленную переменную.

    Проверка пользовательского ввода

    Существует три основных способа проверки пользовательского ввода:

    Предотвращение некорректного пользовательского ввода.

    Пользователь может вводить всё, что хочет, но осуществляется последующая проверка данных. Если проверка прошла успешно, то выполняется перемещение данных в переменную.

    Пользователь может вводить всё, что хочет, но при операции извлечения данных оператором >> параллельно решаются возможные ошибки.

    Некоторые графические пользовательские интерфейсы или расширенные текстовые интерфейсы позволяют проверять ввод пользователя сразу (символ за символом). Программист создает функцию проверки данных, которая принимает и проверяет пользовательский ввод, и, если данные ввода корректны, то возвращается true, если нет — false. Эта функция вызывается каждый раз, когда пользователь нажимает на клавишу. Если функция проверки возвращает true, то символ, который пользователь ввел — принимается. Если функция возвращает false, то символ, который только что ввел пользователь — отбрасывается (и не отображается на экране). Используя этот метод, мы можем гарантировать, что любой пользовательский ввод будет корректным, так как любые неверные нажатия клавиш будут обнаружены и немедленно удалены. К сожалению, std::cin не поддерживает этот тип проверки.

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

    Чаще всего мы позволяем std::cin и оператору извлечения выполнять тяжелую работу. В соответствии с этим методом пользователь может вводить всё, что хочет, а далее std::cin и оператор >> пытаются извлечь данные и, если что-то пойдет не так, выполняется обработка возможных ошибок. Это самый простой способ, и его мы и будем рассматривать.

    Читайте также: