Eof — Поведение EOF в функциях ввода в Си


Содержание

как работает функция eof на cpp?

0 dani1999 [2015-02-20 14:35:00]

Я знаю, что функция «eof» (cpp) возвращает «True» только после неправильной попытки прочитать из файла (а не когда я пришел в конец файла)

Из-за этого, если мы хотим переместить весь файл с 1 на другой, мы должны сделать

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

Но в другой программе это не работает

Я создаю файл grades.txt и пишу на нем «dani»

Он создает «roster.txt», но ничего не копирует.

Но если я использую этот код:

Он создаст файл roster.txt и скопирует «дани» туда

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

2 ответа

Я создаю файл grades.txt и пишу на этом «dani»

Все ваши операции чтения должны завершиться неудачей, поскольку «dani» невозможно извлечь как целое. Это устанавливает битбит потока, но не потребляет никаких символов и поэтому не устанавливает eofbit. Обе программы должны застревать в бесконечном цикле.

fix я not put dani я put «100»

Хорошо, тогда вы не получите бесконечный цикл :) Я написал программу, чтобы продемонстрировать проблему:

Таким образом, поведение eofbit отличается при чтении одного символа по сравнению с чтением форматированного ввода, такого как цифры.

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

Должен работать так же, как и

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

Форматированный вход вызовет условие конца файла, если конец файла достигнут при чтении значения. Это означает, что ваш «исправленный» цикл не сможет вывести окончательное значение, если после него во входном файле ничего не осталось. В частности, если во входном файле есть только одно значение, то никакого вывода не будет.

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

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

Когда же будет этот EOF

Re: Когда же будет этот EOF

Компилируем код gcc: ./a.exe(out) [Ctrl + D] Вылет нормальный, с указанием EOF = -1

Компилируем код bcc32 и после запуска сразу [Ctrl + Z] // Z из-за виндозности Тоже вылет нормальный, с указанием EOF = -1

Наверное компилятор у тебя левый.

Re: Когда же будет этот EOF

Re: Когда же будет этот EOF

Уважаемый, а где проверочка на EOF при чтении символа внутри цикла?
Если EOF случиться при вызове getchar() не в условии while, то и
нужно Вам бужет жать Ctrl+D ещё раз :)

Re: Когда же будет этот EOF

Re: Когда же будет этот EOF

Re: Когда же будет этот EOF


Специально после запуска проги набил пару букв — чтобы в тело цикла был осуществлен вход, потом Ctrl-D — тишина, потом еще раз Ctrl-D и вывел нужный результат, просто интересно даже :)

Re: Когда же будет этот EOF

Re: Когда же будет этот EOF

Мда, просто чедеса — скопировал один в один, запустил — опять надо жать два раза ;( Какой у вас gcc? у меня

gcc version 3.3.5 (Debian 1:3.3.5-5)

Может у кого таже версия? Может попробуете как оно у вас?

Re: Когда же будет этот EOF

Re: Когда же будет этот EOF

>Мда, просто чедеса — скопировал один в один, запустил — опять надо жать два раза

Сделай такой тест — создай текстовый файл, набей в него что-нибудь и выполни команду:

$ proga_kotoruu_ty_skompilil ★ ( 31.08.05 20:36:11 )

Re: Когда же будет этот EOF

Спасибо за ответы! Сейчас под рукой нету Linux, как домой приеду — сразу попробую — идея интересная!

Re: Когда же будет этот EOF

Значит по-порядку; 1) Все тесты с cat были проведены — поведение терминала точно такое же как и у тебя 2)Провел тест с текстовым файлом — программа нормально завершается с нужным результатом

Интересно, что если в непустой строке нажать Ctrl-D, то программа (в нашем случае cat) не завершиться, а выведет то, что было до нее? т.е как было 456

Eof — Поведение EOF в функциях ввода в Си

поскольку строка заканчивается комбинацией перехода на новую строку и возврата каретки(#10#13), то вроде даже так можно:

I originate
You must appreciate, all the others imitate
SCOOTER «GUEST LIST»

‘Pon the mic I’m the teacher!
Spread my words like a preacher!
Yiiihhaaaa.
SCOOTER «WEEKEND»

строка заканчивается нажатием ENTER, поэтому лови «\n», т е:

while ((c = getchar()) != ‘\n’)

Не не не (С) =)
У K&R написан именно EOF. Хочу разобратсья именно с ним.

P.S. Если изменим на ‘\n’ программа сможет работать только со строками. А если нужно вставить текст.
P.P.S. Все равно на выходе вместо количества цифр непонятный массив.

Если ввести Ctrl-Z, то на нем и возвращается EOF.
То есть нормальные строки заканчиваются Enter. После каждой строки будет ‘\n’.
Под конец можно ввести какие-то символы, нажать Ctrl-Z и нажать Enter. Введутся набранные символы и после них EOF

FasterHarder, 10 это и есть ‘\n’. 13 — это ‘\r’. Символы в конце строки ты перепутал местами, хотя при выводе на принтер или экран в двоичном режиме результат выглядит одинаково.
Вот код 13 (вводится Ctrl+Enter) ловить не следует. При вводе в текстовом режиме пара ‘\r’/’\n’ заменяется на один ‘\n’.
Вообще не рекомендуется пользоваться числовым значением. Есть кодировки, в которых перевод строки кодируется по-другому.

I originate
You must appreciate, all the others imitate
SCOOTER «GUEST LIST»

‘Pon the mic I’m the teacher!
Spread my words like a preacher!
Yiiihhaaaa.
SCOOTER «WEEKEND»

I originate
You must appreciate, all the others imitate
SCOOTER «GUEST LIST»

‘Pon the mic I’m the teacher!
Spread my words like a preacher!
Yiiihhaaaa.
SCOOTER «WEEKEND»

Вот тот же ответ в Usenet.

> 12.1b: I have a simple little program that reads characters until EOF,
> but how do I actually *enter* that «EOF» value from the
> keyboard?

> A: It turns out that the value of EOF as seen within your C program
> has essentially nothing to do with the keystroke combination you
> might use to signal end-of-file from the keyboard. Depending on
> your operating system, you indicate end-of-file from the
> keyboard using various keystroke combinations, usually either
> control-D or control-Z.


Как то все очень абстрактно. Не могу понять связи.

Добавлено 27.10.10, 18:52
Прога по Ctrl+Z выходит из цикла

Добавлено 27.10.10, 18:53
А, хотя я там протупил, код ты привел, это я его не заметил

Мда. Можно было бы пост свой подредактировать и высказываться менее категорично IMHO.

По теме: по Ctrl+Z она выходит, да, но для того, чтобы это произошло, нужно вставить Ctrl+Z на пустой строчке, т.е. если набрать что-то типа этого: «dhjjhet^Z» и нажать «Ввод», прога не поймет этого самого EOF, а курсор перейдет на следующую строчку. А нужно чтобы реакция была, как на прерывание, я так полагаю.

P.S. 2KILLER: у тебя код на С++. Я в нем, к сожалению, ничегошеньки не понимаю. =(
WBR

I originate
You must appreciate, all the others imitate
SCOOTER «GUEST LIST»

‘Pon the mic I’m the teacher!
Spread my words like a preacher!
Yiiihhaaaa.
SCOOTER «WEEKEND»

погоди, погоди , я исправил пост выше..

Добавлено 27.10.10, 19:12
ради примера затестил такую прожку:

и в отладчике посмотрел, оказалось, нажатие Ctrl + Z вводит код 26 (непечатаемый символ)..если EOF равен -1, то понятно, что данная программа никогда не завершиться.

N.B. про расширенные коды тоже забывать не стоит.

Добавлено 27.10.10, 19:21

P.S. проверил EOF, да точно -1!

I originate
You must appreciate, all the others imitate
SCOOTER «GUEST LIST»

‘Pon the mic I’m the teacher!
Spread my words like a preacher!
Yiiihhaaaa.
SCOOTER «WEEKEND»

Eof — Поведение EOF в функциях ввода в Си

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

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

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

7.1 Стандартный ввод-вывод

Как уже говорилось в главе 1, библиотечные функции реализуют простую модель текстового ввода-вывода. Текстовый поток состоит из последовательности строк; каждая строка заканчивается символом новой строки. Если система в чем-то не следует принятой модели, библиотека сделает так, чтобы казалось, что эта модель удовлетворяется полностью. Например, пара символов — возврат-каретки и перевод-строки — при вводе могла бы быть преобразована в один символ новой строки, а при выводе выполнялось бы обратное преобразование.

Простейший механизм ввода — это чтение одного символа из стандартного ввода (обычно с клавиатуры) функцией getchar:

В качестве результата каждого своего вызова функция getchar возвращает следующий символ ввода или, если обнаружен конец файла, EOF. Именованная константа EOF (аббревиатура от end of file — конец файла) определена в . Обычно значение EOF равно -1, но, чтобы не зависеть от конкретного значения этой константы, обращаться к ней следует по имени (EOF).

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

будет направлять стандартный вывод не на экран, а в outfile. А командная строка

соединит стандартный вывод программы prog со стандартным вводом программы anotherprog.

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

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

причем она должна быть расположена до первого обращения к вводу-выводу. Если имя заголовочного файла заключено в угловые скобки , это значит, что поиск заголовочного файла ведется в стандартном месте (например в системе UNIX это обычно директорий /usr/include).

Многие программы читают только из одного входного потока и пишут только в один выходной поток. Для организации ввода-вывода таким программам вполне хватит функций getchar, putchar и printf, а для начального обучения уж точно достаточно ознакомления с этими функциями. В частности, перечисленных функций достаточно, когда требуется вывод одной программы соединить с вводом следующей. В качестве примера рассмотрим программу lower, переводящую свой ввод на нижний регистр:

Цукерберг рекомендует:  20 jQuery плагинов для создания модальных окон

Функция tolower определена в . Она переводит буквы верхнего регистра в буквы нижнего регистра, а остальные символы возвращает без изменений. Как мы уже упоминали, «функции» вроде getchar и putchar из библиотеки и функция tolower из библиотеки часто реализуются в виде макросов, чтобы исключить накладные расходы от вызова функции на каждый отдельный символ. В параграфе 8.5 мы покажем, как это делается. Независимо от того, как на той или иной машине реализованы функции библиотеки , использующие их программы могут ничего не знать о кодировке символов.

Упражнение 7.1. Напишите программу, осуществляющую перевод ввода с верхнего регистра на нижний или с нижнего на верхний в зависимости от имени, по которому она вызывается и текст которого находится в arg[0].

7.2 Форматный вывод (printf)


Функция printf переводит внутренние значения в текст.

В предыдущих главах мы использовали printf неформально. Здесь мы покажем наиболее типичные случаи применения этой функции: полное ее описание дано в приложении B.

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

Форматная строка содержит два вида объектов: обычные символы, которые напрямую копируются в выходной поток, и спецификации преобразования, каждая из которых вызывает преобразование и печать очередного аргумента printf. Любая спецификация преобразования начинается знаком % и заканчивается символом-спецификатором. Между % и символом-спецификатором могут быть расположены (в указанном ниже порядке) следующие элементы:

  • Знак минус, предписывающий выравнивать преобразованный аргумент по левому краю поля.
  • Число, специфицирующее минимальную ширину поля. Преобразованный аргумент будет занимать поле по крайней мере указанной ширины. При необходимости лишние позиции слева (или справа при левостороннем расположении) будут заполнены пробелами.
  • Точка, отделяющая ширину поля от величины, устанавливающей точность.
  • Число (точность), специфицирующее максимальное количество печатаемых символов в строке, или количество цифр после десятичной точки — для чисел с плавающей запятой, или минимальное количество цифр — для целого.
  • Буква h, если печатаемое целое должно рассматриваться как short, или l (латинская буква ell), если целое должно рассматриваться как long.

    Символы-спецификаторы перечислены в таблице 7.1. Если за % не помещен символ- спецификатор, поведение функции printf будет не определено. Ширину и точность можно специфицировать с помощью *; значение ширины (или точности) в этом случае берется из следующего аргумента (который должен быть типа int). Например, чтобы напечатать не более max символов из строки s, годится следующая запись:

    Таблица 7.1 Основные преобразования printf

    Символ Тип аргумента; вид печати
    d, i int; десятичное целое
    o unsigned int; беззнаковое восьмеричное (octal) целое (без нуля слева)
    x, X unsigned int; беззнаковое шестнадцатеричное целое (без 0x или 0X слева), для 10. 15 используются abcdef или ABCDEF
    u unsigned int; беззнаковое десятичное целое
    c int; одиночный символ
    s char *; печатает символы, расположенные до знака \0, или в количестве, заданном точностью
    f double; [-]m.dddddd, где количество цифр d задается точностью (по умолчанию равно 6)
    e, E double; [-]m.dddddde±xx или [-]m.ddddddE±xx, где количество цифр d задается точностью (по умолчанию равно 6)
    g, G double; использует %e или %E, если порядок меньше, чем -4, или больше или равен точности; в противном случае использует %f. Завершающие нули и завершающая десятичная точка не печатаются
    p void *; указатель (представление зависит от реализации)
    % Аргумент не преобразуется; печатается знак %

    Большая часть форматных преобразований была продемонстрирована в предыдущих главах. Исключение составляет задание точности для строк. Далее приводится перечень спецификаций и показывается их влияние на печать строки «hello, world», состоящей из 12 символов. Поле специально обрамлено двоеточиями, чтобы была видна его протяженность.

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

    Функция sprintf выполняет те же преобразования, что и printf, но вывод запоминает в строке

    Эта функция форматирует arg1, arg2 и т. д. в соответствии с информацией, заданной аргументом format, как мы описывали ранее, но результат помещает не в стандартный вывод, а в string. Заметим, что строка string должна быть достаточно большой, чтобы в ней поместился результат.

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

    7.3 Списки аргументов переменной длины

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

    Объявление стандартной функции printf выглядит так:

    Многоточие в объявлении означает, что число и типы аргументов могут изменяться. Знак многоточие может стоять только в конце списка аргументов. Наша функция minprintf объявляется как

    поскольку она не будет выдавать число символов, как это делает printf.

    Вся сложность в том, каким образом minprintf будет продвигаться вдоль списка аргументов, — ведь у этого списка нет даже имени. Стандартный заголовочный файл содержит набор макроопределений, которые устанавливают, как шагать по списку аргументов. Наполнение этого заголовочного файла может изменяться от машины к машине, но представленный им интерфейс везде одинаков.

    Тип va_list служит для описания переменной, которая будет по очереди указывать на каждый из аргументов; в minprintf эта переменная имеет имя ap (от «argument pointer» — указатель на аргумент). Макрос va_start инициализирует переменную ap) чтобы она указывала на первый безымянный аргумент. К va_start нужно обратиться до первого использования ap. Среди аргументов по крайней мере один должен быть именованным: от последнего именованного аргумента этот макрос «отталкивается» при начальной установке.

    Макрос va_arg на каждом своем вызове выдает очередной аргумент, а ap передвигает на следующий: но имени типа он определяет тип возвращаемого значения и размер шага для выхода на следующий аргумент. Наконец, макрос va_end делает очистку всего, что необходимо. К va_end следует обратиться перед самым выходом из функции.

    Перечисленные средства образуют основу нашей упрощенной версии prinf.

    Упражнение 7.3. Дополните minprintf другими возможностями printf.

    7.4 Форматный ввод (scanf)

    Функция scanf, обеспечивающая ввод, является аналогом printf; она выполняет многие из упоминавшихся преобразований, но в противоположном направлении. Ее объявление имеет следующий вид:

    Функция scanf читает символы из стандартного входного потока, интерпретирует их согласно спецификациям строки format и рассылает результаты в свои остальные аргументы. Аргумент format мы опишем позже; другие аргументы, каждый из которых должен быть указателем, определяют, где будут запоминаться должным образом преобразованные данные. Как и для printf, в этом параграфе дается сводка наиболее полезных, но отнюдь не всех возможностей данной функции.

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

    Существует также функция sscanf, которая читает из строки (а не из стандартного ввода).


    Функция sscanf просматривает строку string согласно формату format и рассылает полученные значения в arg1, arg2 и т. д. Последние должны быть указателями.

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

  • Пробелы или табуляции, которые игнорируются.
  • Обычные символы (исключая %), которые, как ожидается, совпадут с очередными символами, отличными от символов-разделителей входного потока.
  • Спецификации преобразования, каждая из которых начинается со знака % и завершается символом-спецификатором типа преобразования. В промежутке между этими двумя символами в любой спецификации могут располагаться, причем в том порядке, как они здесь указаны: знак * (признак подавления присваивания); число, определяющее ширину поля; буква h, l или L, указывающая на размер получаемого значения; и символ преобразования (o, d, x).

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

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

    Перед символами-спецификаторами d, l, o, u и x может стоять буква h, указывающая на то, что соответствующий аргумент должен иметь тип short * (а не int *),или l (латинская ell), указывающая на тип long *. Аналогично, перед символами-спецификаторами e, f и g может стоять буква l, указывающая, что тип аргумента — double * (а не float *).

    Таблица 7.2 Основные преобразования scanf

    Символ Вводимые данные; тип аргумента
    d десятичное целое: int *
    i целое: int *. Целое может быть восьмеричным (с 0 слева) или шестнадцатеричным (с 0x или 0X слева)
    o восьмеричное целое (с нулем слева или без него); int *
    u беззнаковое десятичное целое; unsigned int *
    x шестнадцатеричное целое (с 0x или 0X слева или без них); int *
    c символы; char *. Следующие символы ввода (по умолчанию один) размещаются в указанном месте. Обычный пропуск символов- разделителей подавляется; чтобы прочесть очередной символ, отличный от символа-разделителя, используйте %1s
    s Строка символов(без обрамляющих кавычек); char *, указывающая на массив символов, достаточный для строки и завершающего символа ‘\0’, который будет добавлен
    e, f, g число с плавающей точкой, возможно, со знаком; обязательно присутствие либо десятичной точки, либо экспоненциальной части, а возможно, и обеих вместе; float *
    % сам знак %, никакое присваивание не выполняется

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

    Предположим, что нам нужно прочитать строки ввода, содержащие данные вида

    Обращение к scanf выглядит следующим образом:

    Знак & перед monthname не нужен, так как имя массива есть указатель.

    В строке формата могут присутствовать символы, не участвующие ни в одной из спецификаций; это значит, что эти символы должны появиться на вводе. Так, мы могли бы читать даты вида mm/dd/yy с помощью следующего обращения к scanf:

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

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

    В завершение еще раз напомним, что аргументы функций scanf и sscanf должны быть указателями.

    Одна из самых распространенных ошибок состоит в том, что вместо того, чтобы написать

    Компилятор о подобной ошибке ничего не сообщает.

    Упражнение 7.4. Напишите свою версию scanf по аналогии с minprintf из предыдущего параграфа.

    Упражнение 7.5. Перепишите основанную на постфиксной записи программу калькулятора из главы 4 таким образом, чтобы для ввода и преобразования чисел она использовала scanf и/или sscanf.

    7.5 Доступ к файлам

    Во всех предыдущих примерах мы имели дело со стандартным вводом и стандартным выводом, которые для программы автоматически предопределены операционной системой конкретной машины.

    Следующий шаг — научиться писать программы, которые имели бы доступ к файлам, заранее не подсоединенным к программам. Одна из программ, в которой возникает такая необходимость, — это программа cat, объединяющая несколько именованных файлов и направляющая результат в стандартный вывод. Функция cat часто применяется для выдачи файлов на экран, а также как универсальный «коллектор» файловой информации для тех программ, которые не имеют возможности обратиться к файлу по имени. Например, команда

    направит в стандартный вывод содержимое файлов x.c и y.c (и ничего более).

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

    На этот счет имеются простые правила. Для того чтобы можно было читать из файла или писать в файл, он должен быть предварительно открыт с помощью библиотечной функции fopen. Функция fopen получает внешнее имя типа x.c или y.c, после чего осуществляет некоторые организационные действия и «переговоры» с операционной системой (технические детали которых здесь не рассматриваются) и возвращает указатель, используемый в дальнейшем для доступа к файлу.

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

    Цукерберг рекомендует:  Вакансии ООО RAVAK

    Единственное, что требуется для определения указателя файла, — это задать описания такого, например, вида:

    Это говорит, что fp есть указатель на FILE, a fopen возвращает указатель на FILE. Заметим, что FILE — это имя типа) наподобие int, а не тег структуры. Оно определено с помощью typedef. (Детали того, как можно реализовать fopen в системе UNIX, приводятся в параграфе 8.5.)

    Обращение к fopen в программе может выглядеть следующим образом:

    Первый аргумент — строка, содержащая имя файла. Второй аргумент несет информацию о режиме. Это тоже строка: в ней указывается, каким образом пользователь намерен применять файл. Возможны следующие режимы: чтение (read — «r»), запись (write — «w») и добавление (append — «a»), т. е. запись информации в конец уже существующего файла. В некоторых системах различаются текстовые и бинарные файлы; в случае последних в строку режима необходимо добавить букву «b» (binary — бинарный).


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

    Следующее, что нам необходимо знать, — это как читать из файла или писать в файл, коль скоро он открыт. Существует несколько способов сделать это, из которых самый простой состоит в том, чтобы воспользоваться функциями getc и putc. Функция getc возвращает следующий символ из файла; ей необходимо сообщить указатель файла, чтобы она знала откуда брать символ.

    Функция getc возвращает следующий символ из потока, на который указывает *fp; в случае исчерпания файла или ошибки она возвращает EOF.

    Функция putc пишет символ c в файл fp

    и возвращает записанный символ или EOF в случае ошибки. Аналогично getchar и putchar, реализация getc и putc может быть выполнена в виде макросов, а не функций.

    При запуске Си-программы операционная система всегда открывает три файла и обеспечивает три файловые ссылки на них. Этими файлами являются: стандартный ввод, стандартный вывод и стандартный файл ошибок; соответствующие им указатели называются stdin, stdout и stderr; они описаны в . Обычно stdin соотнесен с клавиатурой, а stdout и stderr — с экраном. Однако stdin и stdout можно связать с файлами или, используя конвейерный механизм, соединить напрямую с другими программами, как это описывалось в параграфе 7.1.

    С помощью getc, putc, stdin и stdout функции getchar и putchar теперь можно определить следующим образом:

    Форматный ввод-вывод файлов можно построить на функциях fscanf и fprintf. Они идентичны scanf и printf с той лишь разницей, что первым их аргументом является указатель на файл, для которого осуществляется ввод-вывод, формат же указывается вторым аргументом.

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

    Файловые указатели stdin и stdout представляют собой объекты типа FILE*. Это константы, а не переменные, следовательно, им нельзя ничего присваивать.

    — обратная по отношению к fopen; она разрывает связь между файловым указателем и внешним именем (которая раньше была установлена с помощью fopen), освобождая тем самым этот указатель для других файлов. Так как в большинстве операционных систем количество одновременно открытых одной программой файлов ограничено, то файловые указатели, если они больше не нужны, лучше освобождать, как это и делается в программе cat. Есть еще одна причина применить fclose к файлу вывода, — это необходимость «опорожнить» буфер, в котором putc накопила предназначенные для вывода данные. При нормальном завершении работы программы для каждого открытого файла fclose вызывается автоматически. (Вы можете закрыть stdin и stdout, если они вам не нужны. Воспользовавшись библиотечной функцией freopen, их можно восстановить.)

    7.6 Управление ошибками (stderr и exit)

    Обработку ошибок в cat нельзя признать идеальной. Беда в том, что если файл по какой-либо причине недоступен, сообщение об этом мы получим по окончании конкатенируемого вывода. Это нас устроило бы, если бы вывод отправлялся только на экран, a не в файл или по конвейеру другой программе. Чтобы лучше справиться с этой проблемой, программе помимо стандартного вывода stdout придается еще один выходной поток, называемый stderr. Вывод в stderr обычно отправляется на экран, даже если вывод stdout перенаправлен в другое место. Перепишем cat так, чтобы сообщения об ошибках отправлялись в stderr.

    Программа сигнализирует об ошибках двумя способами. Первый — сообщение об ошибке с помощью fprintf посылается в stderr с тем, чтобы оно попало на экран, а не оказалось на конвейере или в другом файле вывода. Имя программы, хранящееся в argv[0], мы включили в сообщение, чтобы в случаях, когда данная программа работает совместно с другими, был ясен источник ошибки.

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

    Инструкция return exp главной программы main эквивалентна обращению к функции exit(exp). Последний вариант (с помощью exit) имеет то преимущество, что он пригоден для выхода и из других функций, и, кроме того, слово exit легко обнаружить с помощью программы контекстного поиска, похожей на ту, которую мы рассматривали в главе 5. Функция ferror выдает ненулевое значение, если в файле fp была обнаружена ошибка.

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

    Функция feof(FILE *fp) aнaлoгичнa функции ferror; oнa вoзвpaщaeт нeнулевое значение, если встретился конец указанного в аргументе файла.

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

    7.7 Ввод-вывод строк

    В стандартной библиотеке имеется программа ввода fgets, аналогичная программе getline, которой мы пользовались в предыдущих главах.

    Функция fgets читает следующую строку ввода (включая и символ новой строки) из файла fp в массив символов line, причем она может прочитать не более MAXLINE-1 символов. Переписанная строка дополняется символом ‘\0’. Обычно fgets возвращает line, а по исчерпании файла или в случае ошибки — NULL. (Наша getline возвращала длину строки, которой мы потом пользовались, и нуль в случае конца файла.)

    Функция вывода fputs пишет строку (которая может и не заканчиваться символом новой строки) в файл.

    Эта функция возвращает EOF, если возникла ошибка, и неотрицательное значение в противном случае.

    Библиотечные функции gets и puts подобны функциям fgets и fputs. Отличаются они тем, что оперируют только стандартными файлами stdin и stdout, и кроме того, gets выбрасывает последний символ ‘\n’, a puts его добавляет.

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

    Стандарт определяет, что функция ferror возвращает в случае ошибки ненулевое значение; fputs в случае ошибки возвращает EOF, в противном случае — неотрицательное значение.

    С помощью fgets легко реализовать нашу функцию getline:

    Упражнение 7.6. Напишите программу, сравнивающую два файла и печатающую первую строку, в которой они различаются.

    Упражнение 7.7. Модифицируйте программу поиска по образцу из главы 5 таким образом, чтобы она брала текст из множества именованных файлов, а если имен файлов в аргументах нет, то из стандартного ввода. Будет ли печататься имя файла, в котором найдена подходящая строка?

    Упражнение 7.8. Напишите программу, печатающую несколько файлов. Каждый файл должен начинаться с новой страницы, предваряться заголовком и иметь свою нумерацию страниц.

    7.8 Другие библиотечные функции

    В стандартной библиотеке представлен широкий спектр различных функций. Настоящий параграф содержит краткий обзор наиболее полезных из них. Более подробно эти и другие функции описаны в приложении B.


    7.8.1 Операции со строками

    Мы уже упоминали функции strlen, strcpy, strcat и strcmp, описание которых даны в . Далее, до конца пункта, предполагается, что s и t имеют тип char *, c и n — тип int.

    strcat(s,t) — приписывает t в конец s.
    strncat(s,t,n) — приписывает n символов из t в конец s.
    strcmp(s,t) — возвращает отрицательное число, нуль или положительное число для s t, соответственно.
    strncmp(s,t,n) — делает то же, что и strcmp, но количество сравниваемых символов не может превышать n
    strcpy(s,t) — копирует t в s.
    strncpy(s,t,n) — копирует не более n символов из t в s.
    strlen(s) — возвращает длину s.
    strchr(s,c) — возвращает указатель на первое появление символа c в s или, если c нет в s, NULL.
    strrchr(s,c) — возвращает указатель на последнее появление символа c в s или, если c нет в s, NULL.

    7.8.2 Анализ класса символов и преобразование символов

    Несколько функций из библиотеки выполняют проверки и преобразование символов. Далее, до конца пункта, переменная c — это переменная типа int, которая может быть представлена значением unsigned, char или EOF. Все эти функции возвращают значения типа int.

    isalpha(c) — не нуль, если c — буква; 0 в противном случае.
    isupper(c) — не нуль, если c — буква верхнего регистра; 0 в противном случае.
    islower(c) — не нуль, если c — буква нижнего регистра; 0 в противном случае.
    isdigit(c) — не нуль, если c — цифра; 0 в противном случае.
    isalnum(c) — не нуль, если или isalpha(c), или isdigit(c) истинны; 0 в противном случае.
    isspace(c) — не нуль, если c — символ пробела, табуляции, новой строки, возврата каретки, перевода страницы, вертикальной табуляции.
    toupper(c) — возвращает c, приведенную к верхнему регистру.
    tolower(c) — возвращает c, приведенную к нижнему регистру.

    7.8.3 Функция ungetc

    В стандартной библиотеке содержится более ограниченная версия функции ungetch по сравнению с той, которую мы написали в главе 4. Называется она ungetc. Эта функция, имеющая прототип

    отправляет символ c назад в файл fp и возвращает c, а в случае ошибки EOF. Для каждого файла гарантирован возврат не более одного символа. Функцию ungetc можно использовать совместно с любой из функций ввода вроде scanf, getc, getchar и т. д.

    7.8.4 Исполнение команд операционной системы

    Функция system(char *s) выполняет команду системы, содержащуюся в строке s, и затем возвращается к выполнению текущей программы.

    Содержимое s, строго говоря, зависит от конкретной операционной системы. Рассмотрим простой пример: в системе UNIX инструкция

    вызовет программу date, которая направит дату и время в стандартный вывод. Функция возвращает зависящий от системы статус выполненной команды. В системе UNIX возвращаемый статус — это значение, переданное функцией exit.

    7.8.5 Управление памятью

    Функции malloc и calloc динамически запрашивают блоки свободной памяти. Функция malloc

    возвращает указатель на n байт неинициализированной памяти или NULL, если запрос удовлетворить нельзя. Функция calloc

    возвращает указатель на область, достаточную для хранения массива из n объектов указанного размера (size), или NULL, если запрос не удается удовлетворить. Выделенная память обнуляется.

    Указатель, возвращаемый функциями malloc и calloc, будет выдан с учетом выравнивания, выполненного согласно указанному типу объекта. Тем не менее к нему должна быть применена операция приведения к соответствующему типу (Как уже отмечалось (см. примеч. в параграфе 6.5), замечания о приведении типов значений, возвращаемых функциями malloc или calloc, — неверно. — Примеч. авт.), как это сделано в следующем фрагменте программы:

    Функция free(p) освобождает область памяти, на которую указывает p, — указатель, первоначально полученный с помощью malloc или calloc. Никаких ограничений на порядок, в котором будет освобождаться память, нет, но считается ужасной ошибкой освобождение тех областей, которые не были получены с помощью calloc или malloc.

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

    Правильным будет, если вы до освобождения сохраните то, что вам потребуется, как в следующем цикле:

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

    7.8.6 Математические функции

    В описано более двадцати математических функций. Здесь же приведены наиболее употребительные. Каждая из них имеет один или два аргумента типа double и возвращает результат также типа double.

    sin(x) — синус x, x в радианах
    cos(x) — косинус x, x в радианах
    atan2(y,x) — арктангенс y/x, y и x в радианах
    exp(x) — экспоненциальная функция e в степени x
    log(x) — натуральный (по основанию e) логарифм x (x>0)
    log10(x) — обычный (по основанию 10) логарифм x (x>0)
    pow(x,y) — x в степени y
    sqrt(x) — корень квадратный x (x > 0)
    fabs(x) — абсолютное значение x
    Цукерберг рекомендует:  C# - c# VS код работает через f11 но не работает через f5

    7.8.7 Генератор случайных чисел

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

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

    Функция srand(unsigned) устанавливает семя для rand. Реализации rand и srand, предлагаемые стандартом и, следовательно, переносимые на различные машины, рассмотрены в параграфе 2.7.

    Упражнение 7.9. Реализуя функции вроде isupper, можно экономить либо память, либо время. Напишите оба варианта функции.

    Функция EOF EOF function

    Возвращает аргумент Integer, содержащий логическое значение True, когда достигнут конец файла, открытого для случайного или последовательного ввода. Returns an Integer containing the Boolean value True when the end of a file opened for Random or sequential Input has been reached.

    Синтаксис Syntax

    Конец файла (FileNumber) EOF(filenumber)


    Обязательный __ аргумент FileNumber — это целое число, содержащее любой допустимый номер файла. The required filenumber argument is an Integer containing any valid file number.

    Примечания Remarks

    Используйте функцию EOF, чтобы избежать ошибок, вызываемых попытками выполнить ввод после конца файла. Use EOF to avoid the error generated by attempting to get input past the end of a file.

    Функция EOF возвращает значение False, пока не будет достигнут конец файла. The EOF function returns False until the end of the file has been reached. Если файлы открыты в случайном или двоичном доступе, EOF возвращает false до тех пор, пока не удается прочитать всю запись в последнем исполненном операторе Get . With files opened for Random or Binary access, EOF returns False until the last executed Get statement is unable to read an entire record.

    При наличии файлов, **** открытых для двоичного доступа, попытка чтения файла с помощью функции input , пока EOF возвращает значение true , приводит к ошибке. With files opened for Binary access, an attempt to read through the file by using the Input function until EOF returns True generates an error. Используйте функции LOF и Loc вместо EOF при чтении двоичных файлов с входными даннымиили используйте Get при использовании функции EOF . Use the LOF and Loc functions instead of EOF when reading binary files with Input, or use Get when using the EOF function. Когда файлы открыты для вывода, функция EOF всегда возвращает True. With files opened for Output, EOF always returns True.

    Пример Example

    В этом примере используется функция EOF для обнаружения конца файла. This example uses the EOF function to detect the end of a file. В этом примере предполагается, что MYFILE это текстовый файл с несколькими строками текста. This example assumes that MYFILE is a text file with a few lines of text.

    См. также See also

    Поддержка и обратная связь Support and feedback

    Есть вопросы или отзывы, касающиеся Office VBA или этой статьи? Have questions or feedback about Office VBA or this documentation? Руководство по другим способам получения поддержки и отправки отзывов см. в статье Поддержка Office VBA и обратная связь. Please see Office VBA support and feedback for guidance about the ways you can receive support and provide feedback.

    EOF (End-of-file)

    EOF (англ. End-of-file ) в компьютерной терминологии — индикатор операционной системы, означающий, что данные в источнике (файлы, потоки и т.д.) закончились.

    Значение EOF

    В языке СИ

    В стандартной библиотеке языка Си функции ввода-вывода могут возвращать значение, равное макроопределению EOF для индикации достижения конеца файла или потока. Реальное значение EOF является отрицательным числом, которое зависит от системы (чаще всего −1), для гарантии несовпадение с кодом символа. Значение EOF определено в stdio.h.

    В UNIX подобных ОС

    Терминал не вернет настоящий индикатор EOF, если устройство не выключено и исправно, но если требуется ввести более одного файла в терминал, то можно воспользоваться EOF. В UNIX сигнал о событии, что была нажата клавиша EOF обрабатывается драйвером, поэтому программам не нужно различать терминал от других входных файлов. По умолчанию, драйвер преобразует Control-D символ в начале строки в индикатор конца файла. Чтобы вставить реальный Control-D (ASCII 04) символ во входной поток, пользователь предварительно отправляет командный символ (обычно Control-V). В AmigaDOS используется Control-\ вместо Control-D.

    В ОС Windows/DOS

    В таких операционных системах как Windows и MS-DOS, а также в ОС CP/M и множестве операционных систем DEC, терминал никогда не вернет значение EOF. Вместо этого программы различают, что источник данных является терминал или другое символьное устройство и интерпретируют зарезервированный символ или последовательность как символ конца файла индикатора. Чаще всего это ASCII Control-Z, код 26. Для указания «EOF» в таких операционных системах как Windows и MS-DOS, а также в ОС CP/M и множестве операционных систем DEC, следует воспользоваться комбинацией клавиш Ctrl+Z.

    В стандарте ANSI X3.27-1969

    В ANSI X3.27-1969 (стандарт магнитных лент), на конец файла указывает метка на ленте, которая представляет собой щель на ленте, за которой следует один байт со значением 0xD(hex) для ленты с девятью дорожками или со значением 17(oct) для ленты с семью дорожками.

    Функция EOF

    Примечание: Функция, метод, объект или свойство, описанные в данном разделе, отключаются, если служба обработки выражений Microsoft Jet выполняется в режиме песочницы, который не позволяет рассчитывать потенциально небезопасные выражения. Для получения дополнительных сведений выполните в справке поиск по словам «режим песочницы».

    Возвращает значение типа Integer, соответствующее логическому значению True при достижении конца файла, открытого в режиме Random или последовательного ввода ( Input).

    Обязательный TE000127245 номер_файла — это значение типа Integer, содержащее допустимый TE000126488.

    Функция EOF служит для предотвращения ошибок при попытке ввода данных после достижения конца файла.

    Функция EOF возвращает значение False до тех пор, пока не будет достигнут конец файла. Если файл открыт в режиме доступа Random или Binary, функция EOF возвращает значение False до тех пор, пока возможно чтение всей записи в файле при помощи инструкции Get.

    Если файлы открыты в режиме Binary, попытка считывать файл с помощью функции Input до тех пор, пока функция EOF не возвратит значение True, приведет к ошибке. Следует использовать функции LOF и Loc вместо EOF при чтении двоичных файлов с помощью функции Input либо использовать функцию Get при вызове функции EOF. Если файл открыт в режиме Output, функция EOF всегда возвращает значение True.

    Пример

    Примечание: В примерах ниже показано, как использовать эту функцию в модуле Visual Basic для приложений (VBA). Чтобы получить дополнительные сведения о работе с VBA, выберите Справочник разработчика в раскрывающемся списке рядом с полем Поиск и введите одно или несколько слов в поле поиска.

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

    Пробуем с EOF в C

    Я пишу программу, которая должна читать две строки, которые могут содержать разрывы строк и различные другие символы. Поэтому я использую EOF (Ctrl-Z или Ctrl-D), чтобы завершить строку.


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

    Я попытался очистить буфер с помощью while (getchar() != ‘\n’); и нескольких похожих вариантов, но, похоже, ничего не помогло. Все попытки очистки приводили к бесконечному циклу, и без очистки добавление второй переменной невозможно.

    Символы для обеих переменных читаются в цикле примерно так: while((c = getchar()) != EOF) , что говорит о том, что это EOF, что я застрял в моем буфере. Или это как-то влияет на поведение программы? Что-то не так с используемой логикой?

    Я начинаю чувствовать себя немного отчаянным после нескольких часов борьбы с этим.

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

    Итак, вы должны определить, что каждая переменная вводится отдельной строкой, и пользователи должны нажимать Enter вместо EOF. Вам все равно нужно проверить, получил ли вы eof, потому что это означает, что пользователь действительно набрал EOF, и вы ничего не увидите — в этом случае вам нужно вырваться из цикла и вывести сообщение об ошибке.

    EOF не является символом — это специальное значение, возвращаемое функциями ввода, чтобы указать условие, что «конец файла» на этом входном потоке достигнут. Как говорит Мартин против Лёвиса, когда это условие «конца файла» происходит, это означает, что в этом потоке не будет больше входных данных.

    Путаница возникает из-за того, что:

    • Многие типы терминалов распознают специальное нажатие клавиши, чтобы сигнализировать «конец файла», когда «файл» является интерактивным терминалом (например, Ctrl-Z или Ctrl-D); и
    • Значение EOF является одним из значений, которое может быть возвращено семейством функций getchar() .

    Вам нужно будет использовать фактическое значение символа для разделения входов — символ ASCII nul ‘\0’ может быть хорошим выбором, если он не может отображаться как допустимое значение внутри самих входов.

    Описание функций языка Си

    All | _ | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z

    feof – проверка наличия признака конца файла.

    #include
    int feof (FILE *stream );

    stream – указатель на управляющую таблицу потока данных к которому привязан проверяемый файл.

    Ненулевое значение если обнаружен установленный признак конца файла, иначе ноль.

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

    В примере из заранее созданного файла test.txt располагающегося в одной папке с программой считываются данные с помощью функции fgetc, пока не будет достигнут конец файла. Признак конца файла определяется с помощью функции feof. В файле заранее сохранена строка: «тест чтения». Считанные данные и отчет о работе выводятся на консоль

    Открытие файла: выполнено
    Коды считанных символов:
    212 197 211 212 32 222 212 197 206 201 209
    Чтение файла закончено
    Закрытие файла: выполнено

    Функция EOF EOF function

    Возвращает аргумент Integer, содержащий логическое значение True, когда достигнут конец файла, открытого для случайного или последовательного ввода. Returns an Integer containing the Boolean value True when the end of a file opened for Random or sequential Input has been reached.

    Синтаксис Syntax

    Конец файла (FileNumber) EOF(filenumber)

    Обязательный __ аргумент FileNumber — это целое число, содержащее любой допустимый номер файла. The required filenumber argument is an Integer containing any valid file number.

    Примечания Remarks

    Используйте функцию EOF, чтобы избежать ошибок, вызываемых попытками выполнить ввод после конца файла. Use EOF to avoid the error generated by attempting to get input past the end of a file.

    Функция EOF возвращает значение False, пока не будет достигнут конец файла. The EOF function returns False until the end of the file has been reached. Если файлы открыты в случайном или двоичном доступе, EOF возвращает false до тех пор, пока не удается прочитать всю запись в последнем исполненном операторе Get . With files opened for Random or Binary access, EOF returns False until the last executed Get statement is unable to read an entire record.

    При наличии файлов, **** открытых для двоичного доступа, попытка чтения файла с помощью функции input , пока EOF возвращает значение true , приводит к ошибке. With files opened for Binary access, an attempt to read through the file by using the Input function until EOF returns True generates an error. Используйте функции LOF и Loc вместо EOF при чтении двоичных файлов с входными даннымиили используйте Get при использовании функции EOF . Use the LOF and Loc functions instead of EOF when reading binary files with Input, or use Get when using the EOF function. Когда файлы открыты для вывода, функция EOF всегда возвращает True. With files opened for Output, EOF always returns True.

    Пример Example

    В этом примере используется функция EOF для обнаружения конца файла. This example uses the EOF function to detect the end of a file. В этом примере предполагается, что MYFILE это текстовый файл с несколькими строками текста. This example assumes that MYFILE is a text file with a few lines of text.

    См. также See also

    Поддержка и обратная связь Support and feedback

    Есть вопросы или отзывы, касающиеся Office VBA или этой статьи? Have questions or feedback about Office VBA or this documentation? Руководство по другим способам получения поддержки и отправки отзывов см. в статье Поддержка Office VBA и обратная связь. Please see Office VBA support and feedback for guidance about the ways you can receive support and provide feedback.

  • Понравилась статья? Поделиться с друзьями:
    Все языки программирования для начинающих