Freopen открыть файл повторно


Содержание

Как можно повторно открыть файловый поток и опорожнение без имени файла?

Скажем, у меня есть файловый поток.

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

Он по-прежнему говорит, что «тест» в выходном файле.

Попробуйте следующее. Основная идея заключается в том, чтобы получить дескриптор файла из потока, но вам все еще нужно, чтобы закрыть поток, поэтому я DUP дескриптора файла, чисто закрыть поток, а затем вызвать ftruncate на дубликате дескриптора файла, минуя поток.

stdin — открытие нескольких файлов с помощью freopen в Stack Overflow

Я пытаюсь использовать freopen () несколько раз для чтения и закрытия разных файлов.
Итак, вот что я сделал внутри своей основной функции:

Но оказывается, что первая часть, // do something. работает нормально (читает с std::cin без проблем) но цикл while во втором, похоже, не запускается.
Входные файлы имеют правильный формат, поэтому я не знаю, почему std::cin >> command возвращает ложь

Решение

В соответствии freopen(argv[2], «r», stdin); вы пытаетесь открыть снова stdin , Но вы уже закрылись stdin в соответствии fclose(stdin); как раз перед этим Также, stdin теперь висячий указатель после закрытия файл.

Ниже приводится выдержка из www.cplusplus.com :

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

Вы должны использовать fopen() функция после закрытия stdin ,

Работа с файлами на php: открытие, запись, чтение

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

Файлы php

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

Для работы с файлами php используются специальные приложения – программные редакторы. Наиболее распространенными из них являются:

  • Dreamweaver.
  • PHPEdit.
  • Eclipse PHP Development.

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

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

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

Открытие и закрытие файлов

В php все операции с файлами осуществляются в несколько этапов:

  • Открытие файла;
  • Редактирование содержимого;
  • Закрытие файла.

Для открытия файла используется функция fopen() . Ее синтаксис:

  • string filename – имя файла или абсолютный путь к нему. Если путь к файлу не будет указан, то будет произведен его поиск в текущем каталоге. При отсутствии искомого файла система выведет сообщение об ошибке. Пример:
  • string mode – указывает режим открытия файла. Принимаемые аргументом значения:
  • r – файл открыт только для чтения, файловый указатель устанавливается в начале;
  • r+ – файл открыт для чтения и записи;
  • w – создается новый файл только для записи. Если файл с таким именем уже существует, в нем происходит автоматическое удаление всех данных;
  • w+ — создается новый файл для записи и чтения. При существовании такого файла происходит полная перезапись его данных на новые;
  • a – файл открыт для записи. Указатель устанавливается в конце. То есть запись в файл php начнется не с начала, а с конца;
  • a+ – открытие файла в режиме чтения и записи. Запись начнется с конца;
  • b – режим работы с файлом, содержащим в себе двоичные данные (в двоичной системе исчисления). Этот режим доступен только в операционной системе Windows.

Для закрытия доступа к файлу служит функция fclose () . Синтаксис:

int fclose (int file) , где int file – дескриптор сайта, который нужно закрыть.

Чтение и запись файлов

Для простого отображения всего содержимого файла идеально подходит функция readfile () . Ее синтаксис:

readfile (string filename) , где string filename – строковое имя фала ( не дескриптор ).

Тот же самый файл можно прочитать с помощью функции fpassthru () . Она считывает данные от конечной позиции указателя и до конца файла. Ее синтаксис:

Для работы с функцией требуется открытие и закрытие файла. Пример:

Результат аналогичен предыдущему.

Функции для работы с файлами в php позволяют считывать содержимое построчно и посимвольно:

  • string fgets ( int file, int length) – функция считывает строку длиною length . Пример:
  • string fread (int file, int length) – по действию идентична предыдущей.

Для записи текстовых данных в файл существует две идентичные функции:

  • int fputs ( int file, string string [, int length ])
  • int fwrite ( int file, string string [, int length ])

Функции записывают в файл int file строку string string указанной длины int length ( необязательный аргумент ). Пример:

Создание и удаление файлов

Чтобы создать файл php , можно использовать функцию fopen() в режиме доступа « w » или « w+ ». Или функцию touch () . Она устанавливает время изменения файла. При отсутствии элемента с искомым именем он будет создан. Ее синтаксис:

Для создания копии файла используется функция copy() . В качестве аргументов она принимает имя оригинала и файла, куда нужно скопировать содержимое. Если он не существует, то будет создан. Синтаксис функции:

Удалить файл можно с помощью функции unlink() . Ее синтаксис:

Получение информации о файле

Для получения информации о файлах в php используется целый ряд функций:

  • bool fileexists (string filename) – проверяет, существует ли элемент;
  • int fileatime (string filename) – возвращает время последнего открытия;
  • int filesize (string filename) – возвращает байтовый размер файла;
  • string filetype (string filename) – тип файла.

Это еще не все возможности для работы с файлами, реализованные в php . Многие из методов и функций остались за кадром. Так что простор для самостоятельного познания еще велик.

Freopen открыть файл повторно

Работа с файлами производится в сеансовом режиме. Это значит, что функция открытия файла устанавливает связь между открытым файлом и идентифицирующим его элементом в программе. Идентификатором файла (в некоторых библиотеках) может быть целое число ( handle ). В стандартной библиотеке используется указателе на структурированную переменную – описатель (дескриптор) файла в библиотеке типа FILE *. При выполнении операций чтения-записи и при закрытии файла нужно использовать этот идентификатор как параметр функций ввода-вывода.

FILE * fopen (char *name, char *mode)

Результат FILE * — указатель на описатель файла или NULL

fd – идентификатор файла (указатель на описатель)

name – строка с именем файла

mode – строка режима работы с файлом

int fclose (FILE * fd )

FILE * freopen (char *name, char *mode, FILE * fd )

Закрыть и открыть повторно

FILE * tmpfile ( void )

Создать и открыть временный с уникальным именем

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

Стандартная библиотека ввода-вывода ориентирована на работу в режиме командной строки (консольного приложения). Стандартные потоки ввода-вывода (клавиатура, экран) представляют собой «файлы», открытые перед выполнением main . Они так и объявлены в библиотеке, а функции, работающие со стандартным вводом, представляют собой частный случай работы с файлами.

extern FILE * stdin , * stdout , * stderr , * stdaux , * stdprn ; // Имеется в stdio.h

# define getchar () getc ( stdin )

При запуске программы в режиме командной строки stdin и stdout могут быть перенаправлены на любые текстовые файлы (например, ввод из a . txt , вывод в c :\ xx \ b . txt ).

test.exe a.txt >c:\xx\b.txt

Посимвольный ввод-вывод

Первая группа функций ввода-вывода передает «за один присест» по одному символу текста из потока или в поток.

int getc (FILE * fd )

Явно указанный файл

Код символа или EOF

inc getchar ( void )

int ungetc ( int ch , FILE * fd )

Возвратить символ в файл (повторно читается)

int putc ( int ch , FILE * fd )

Явно указанный файл

Код символа или EOF

inc putchar ( int ch )

Примечание: хотя функции и выполняют ввод отдельного символа, обычно он осуществляется в стандартном режиме построчного ввода, поддерживаемого операционной системой в режиме командной строки («эхо »- печать вводимых символов, редактирование строки). Поэтому в библиотеку строка попадает только полностью, после ввода символа «конец строки», а уже затем выдается в программу посимвольно. Для немедленного реагирования программы на введенный символ или отказ от эхо-печати необходимо пользоваться нестандартными библиотеками (например, conio.h ).

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

int isalpha (char cc)<

return cc>=’a’ && cc =’A’ && cc

FILE *fd1= fopen ( «45-01.cpp»,»r»); // Чтение файла

FILE *fd2=fopen(«45-01.txt»,» w «); // Создание и запись файла

if (fd1==NULL || fd2==NULL) return;

i=1; // Читать слово в массив

while( isalpha ( ss = getc (fd1))) c[ i ++]= ss ;

for( i —; i >=0;i—) putc (c[ i ],fd2);

putc (ss,fd2); // Вывести в обратном порядке

> // а также символ – после слова

else putc (c[0],fd2);

fclose ( fd1); fclose (fd2); >

Построчный ввод-вывод

char * fgets (char * str , int n, FILE * fd )

Явно указанный файл

n — максимальная длина строки

str или NULL(ошибка)

char * gets ( char * str )

char * fputs (char * str , FILE * fd )

Явно указанный файл

str или NULL(ошибка)

char * puts ( char * str )

При построчном вводе-выводе нужно учитывать, что строка в файле (потоке) и в памяти – не совсем одно и то же, в первом случае она является последовательностью символов произвольной длины, ограниченной символом ‘ \ n ‘, а во втором случае она размещена в массиве заданной размерности и ограничена символом ‘ \0’. Отсюда нюансы:

· при построчном вводе необходимо обеспечить соответствие между длиной строки в файле (которая, в принципе, может быть любой) и размерностью массива символом. Контроль за этим осуществляется так: функция задает размерность массива символов. Если строка короче, то она будет иметь в массиве два ограничителя – символы ‘ \ n ’ и ‘ \0’ (конец строки в потоке и в памяти), если же нет, то только символ ‘ \0’. Если этот факт игнорировать, то длинные строки при чтении из файла будут «порезаны» на части.

Форматированный ввод-вывод

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

int fprintf (FILE * fd , char format[]. )

Явно указанный файл

Число фактических параметров, для которых введены значения, или EOF

int printf ( char format [] . )

int sprintf (char str [], char format[]. )

Строка в памяти

int fprintf (FILE * fd , char format[]. )

Явно указанный файл

Число выведенных байтов или EOF

int printf ( char format [] . )

int sprintf (char str [], char format[]. )

Строка в памяти

Форматная строка представляет собой шаблон, задающий выводимый в поток текст. В определенные места текста подставляются значения переменных из списка, следующего за форматной строкой. Место подстановки значения очередной переменной определяется символом « %» (спецификация формата). Спецификация имеет ряд необязательных параметров и один обязательный – тип подставляемой переменной. Ее вид — % [флаги ][ ширина][.точность][модификатор] тип.

выравнивание по левому краю поля

выводится знак числа («+» или » -» )

выводится пробел перед положительным числом

выводится идентификатор системы счисления (0- восьмеричная , 0 x -шестнадцатеричная)

минимальная ширина поля n (незаполненные позиции — пробелы)

то же, незаполненные позиции – нули

задается следующим фактическим параметром функции

количество цифр дробной части

long ( l – long int , lf – double)


unsigned шестнадцатеричное (цифры A .. F )

float в формате xxx . xxxexxx

float в формате xxx . xxxExxx

float в формате xxx . xxx

char * или char [] – массив символов (строка)

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

· в форматном вводе-выводе источником данных может быть, кроме файла, строка символов (функции sscanf , sprintf ), они имеют дополнительный параметр – массив символов – источник данных;

Илон Маск рекомендует:  Построение таблицы из csv-файла на PHP

· при форматном вводе функция читает ровно столько символов, сколько определяется спецификаторами ввода, а разделители возвращает во входной поток. Поэтому следует аккуратно «мешать» форматированный ввод с посимвольным и построчным. Например, если в строке содержится два целых числа, которые читаются функцией fscanf , то следующая функция fgets прочитает пустую строку, т.к. символ конца строки, ограничивающий второе число, будет возвращен во входной поток;

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

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

Последовательность, заданная форматом

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

· последовательное размещение разных форматных единиц друг за другом;

· повторение нескольких форматных единиц в цикле с использованием счетчика повторений или элемента-ограничителя;

· выбор одной из нескольких форматных единиц в зависимости от значения элемента-селектора;

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

Элементы в форматной последовательности несут различную функциональную нагрузку:

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

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

4 5 6 -1 2.55 3 3 -1 4.75 3 0

4 5 6 6 6 6 6 7 7 2 3 6 6 6 6 0 // до сжатия

4 6 -5 6 -2 7 2 3 -4 6 0 // после сжатия

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

// Чтение последовательностей различных форматов

double F1(char c[])<

FILE * fd = fopen ( c,»r «); // Открыть файл

fscanf ( fd ,»% d «,& v ); // Читать очередное значение

if (v==0) break ; // Ограничитель — 0

if ( v >0) s+=v ; // Если >0 — добавить к сумме

s+=dd ; // за ним — вещественное

fclose ( fd ); return s;>

int F2(char c[], int d[])<

FILE * fd = fopen ( c,»r «); // Открыть файл

double s=0; int n=0;

fscanf ( fd ,»% d «,& v ); // Читать очередное значение

if (v==0) break ; // Ограничитель — 0

if ( v >0) d [ n++ ]= v ; // Если >0 — добавить в массив

int k=-v ; // Если fscanf ( fd ,»% d «,& v );// Следующее значение — повторяющееся

while ( k —!=0) // Цикл копирования повторяющегося

d [ n ++]= v ; // значения

fclose ( fd ); return n;>

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

Freopen открыть файл повторно

FILE *fopen(const char * path , const char * mode );
FILE *fdopen(int fildes , const char * mode );
FILE *freopen(const char * path , const char * mode , FILE * stream );

ОПИСАНИЕ

Параметр mode указывает на строку, начинающуюся с одной из следующих последовательностей (за ними могут следовать дополнительные символы): r Открыть текстовый файл для чтения. Чтение начинается с начала файла. r+ Открыть для чтения и записи. Чтение или запись начинаются с начала файла. w «Урезать» файл до нулевой длины или создать текстовый файл и открыть его для записи. Запись начинается с начала файла. w+ Открыть для чтения и записи. Файл создается, если до этого его не существовало, в противном случае он «урезается». Чтение или запись начинаются с начала файла. a Открыть для дописывания (записи в конец файла). Файл создается, если до этого его не существовало. Запись осуществляется в конец файла. a+ Открыть для чтения и дописывания (записи в конец файла). Файл создается, если до этого его не существовало. Чтение или запись производятся с конца файла.

Строка mode может также включать в себя символ «b» в качестве последнего символа или символа, входящего в любые описанные выше двухсимвольные комбинации. Это требование является строгим только в случае, если требуется совместимость этой версии с ANSI X3.159-1989 («ANSI C»); символ «b» игнорируется во всех POSIX-совместимых системах, включая Linux. Другие системы могут иначе обращаться к текстовым и бинарным файлам, и добавление «b» может оказаться полезным, если Вы осуществляете ввод-вывод в двоичный файл; возможно, Ваша программа будет когда-нибудь работать с не-Unix окружением.

Любой созданный файл будет иметь атрибуты S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH (0666), как модифицированный величиной umask процесса (см. umask (2) ).

Чтение и запись могут накладываться друг на друга в потоке, открытом для чтения/записи, в любом порядке. Заметим, что ANSI C требует, чтобы между чтением/записью использовались функции позиционирования в файле, пока операция ввода не встретит конец файла. Если это условие не выполняется, то при чтении разрешается возвращать результат, не совпадающий с самым последним изменением. То есть будет хорошим тоном (а иногда и действительно необходимым в Linux) использовать функции fseek или fgetpos между операциями чтения и записи в одном потоке. Эти операции могут фактически быть «пустыми» (как, например, fseek(. 0L,SEEK_CUR) , вызванная для того, чтобы возник ее побочный эффект синхронизации).

Открытие файла в режиме дописывания ( a в качестве первого символа mode ) приводит к тому, что все последующие операции записи в этот поток производятся в конец файла, как если бы перед ними была вызвана функция fseek(stream,0,SEEK_END);

Функция fdopen связывает поток с существующим описателем файла fildes . Режим mode потока (одно из следующих значений: «r», «r+», «w», «w+», «a», «a+») должен быть совместим с режимом описателя файла. Указатель файловой позиции в новом потоке принимает значение, равное значению fildes , а указатели ошибок и конца файла по значению равны нулю. Режимы «w» или «w+» не «урезают» файл. Описатель файла не скопирован и будет закрыт, когда поток, созданный fdopen , закрывается. Результат применения fdopen в общем объекте памяти неопределен.

Функция freopen открывает файл с именем path и связывает его с потоком stream . Исходный поток (если такой существовал) закрывается. Параметр mode используется, как и в функции fopen . Основной задачей функции freopen является изменение файла, связанного со стандартным текстовым потоком ( stderr , stdin , or stdout ).

ВОЗВРАЩАЕМЫЕ ЗНАЧЕНИЯ


НАЙДЕННЫЕ ОШИБКИ

Функции fopen , fdopen и freopen при ошибках устанавливают значение errno равным какому-либо значению из определенных в malloc (3).

Функция fopen при ошибках устанавливает значение errno равным какому-либо значению из определенных в open (2).

Функция fdopen при ошибках устанавливает значение errno равным какому-либо значению из определенных в fcntl (2).

Функция freopen при ошибках устанавливает errno равным какому-либо значению из определенных в open (2), fclose (3) и fflush (3).

Работа с файлами

10.1.2. Двоичные файлы

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

Создание двоичных файлов с помощью функции fopen отличается от создания текстовых файлов только указанием режима обмена – «rb» (двоичный для чтения), «rb+» (двоичный для чтения и записи), «wb» (двоичный для записи), «wb+» (двоичный для записи и чтения):

Обычно для обмена с двоичными файлами используются функции fread и fwrite :

  • buf – указатель типа void* на начало буфера в оперативной памяти, из которого информация переписывается в файл;
  • size_rec – размер передаваемой порции в байтах;
  • n_rec – количество порций, которое должно быть записано в файл;
  • f1 – указатель на блок управления файлом;
  • c_w – количество порций, которое фактически записалось в файл.

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

  • c_r – количество порций, которое фактически прочиталось из файла;
  • buf – указатель типа void* на начало буфера в оперативной памяти, в который информация считывается из файла.

Обратите внимание на значения, возвращаемые функциями fread и fwrite . В какой ситуации количество записываемых порций может не совпасть с количеством записавшихся данных? Как правило, на диске не хватило места, и на такую ошибку надо реагировать. А вот при чтении ситуация, когда количество прочитанных порций не совпадает с количеством запрашиваемых порций, не обязательно является ошибкой. Типичная картина – количество данных в файле не кратно размеру заказанных порций.

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

  • f1 – указатель на блок управления файлом;
  • delta – величина смещения в байтах, на которую следует переместить указатель файла;
  • pos – позиция, от которой производится смещение указателя (0 или SEEK_SET – от начала файла, 1 или SEEK_CUR – от текущей позиции, 2 или SEEK_END – от конца файла)

Кроме набора функций fopen /fclose, fread /fwrite > для работы с двоичными файлами в библиотеке BC предусмотрены и другие средства – _dos_open /__dos_close, _dos_read /_dos_write, _create /_close, _read /_write . Однако знакомство со всеми возможностями этой библиотеки в рамках настоящего курса не предусмотрено.

Пример 2. Рассмотрим программу, которая создает двоичный файл для записи с именем c_bin и записывает в него 4*10 порций данных в машинном формате (строки, целые и вещественные числа). После записи данных файл закрывается и вновь открывается для чтения. Для демонстрации прямого доступа к данным информация из файла считывается в обратном порядке – с конца. Контроль записываемой и считываемой информации обеспечивается дублированием данных на экране дисплея.

Использованные в этом примере операторы:

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

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

10.1.3. Структурированные файлы

Структурированный файл является частным случаем двоичного файла, в котором в качестве порции обмена выступает структура языка C, являющаяся точным аналогом записи в Паскале. По сравнению с предыдущим примером использование записей позволяет сократить количество обращений к функциям fread /fwrite , т.к. в одном обращении участвуют все поля записи.

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

Пример 3. Приведенная ниже программа является модификацией предыдущего примера. Единственное ее отличие состоит в использовании структуры (записи) b , состоящей из символьного ( b.s , 5 байт, включая нулевой байт – признак конца строки), целочисленного ( b.n , 2 байта в BC и 4 байта в BCB) и вещественного ( b.r , 4 байта) полей.

Результат работы этой программы ничем не отличается от предыдущего примера.

Считывание данных из файла. Не могу открыть файл через fopen() !

Я в ступоре! Имеем простой пример

Компилим его под Visual C++ 6. В каталоге с exe-шником лежит файл file.txt. При запуске получаем

Пробовал указывать файл как «.\file.txt», и скопировов его в корень C:, указываю как «c:\file.txt». Ни один вариант не проходит, файл не виден. Атрибуты у файла обычные (в FAR нет ни одной галки на атрибутах файла).

Почему файл не открыватеся.
Что-то нужно включать/выключать в опциях компилятора?
Или это я что-то не так делаю?

1) Если программа запускается непосредственно из Visual Studio и файл file.txt лежит в папке Debug/Release вместе с .exe, то необходимо его перенести в папку проекта (там, где лежит *.dsp-файл) — рабочая папка программы по умолчанию там (сделано для того, чтобы она была одинакова для Debug и Release сборок)
2) Необходимо писать путь как «C:\\file.txt» или «C:/file.txt»

Путь пишется так: c:\\file.txt т.к. символ \ зарезервирован

gamedev.com.ua
ты написал то же что и автор, только ещё и коряво.

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

xintrea
тупой копипаст из демки Bullet

Господа, все оказалось так, как написал Genx

1) Если программа запускается непосредственно из Visual Studio и файл file.txt лежит в папке Debug/Release вместе с .exe, то необходимо его перенести в папку проекта (там, где лежит *.dsp-файл) — рабочая папка программы по умолчанию там (сделано для того, чтобы она была одинакова для Debug и Release сборок)
2) Необходимо писать путь как «C:\\file.txt» или «C:/file.txt»

Теперь файл открывается. Но сразу возникла другая проблема — файл не считывается (!) через функцию getc().

Работа с файлами

Для удобства обращения информация в запоминающих устройствах хранится в виде файлов.

Файл – именованная область внешней памяти, выделенная для хранения массива данных. Данные, содержащиеся в файлах, имеют самый разнообразный характер: программы на алгоритмическом или машинном языке; исходные данные для работы программ или результаты выполнения программ; произвольные тексты; графические изображения и т. п.

Каталог ( папка , директория ) – именованная совокупность байтов на носителе информации, содержащая название подкаталогов и файлов, используется в файловой системе для упрощения организации файлов.

Файловой системой называется функциональная часть операционной системы, обеспечивающая выполнение операций над файлами. Примерами файловых систем являются FAT (FAT – File Allocation Table, таблица размещения файлов), NTFS, UDF (используется на компакт-дисках).

Существуют три основные версии FAT: FAT12, FAT16 и FAT32. Они отличаются разрядностью записей в дисковой структуре, т.е. количеством бит, отведённых для хранения номера кластера. FAT12 применяется в основном для дискет (до 4 кбайт), FAT16 – для дисков малого объёма, FAT32 – для FLASH-накопителей большой емкости (до 32 Гбайт).

Илон Маск рекомендует:  Шаблон сайта со слайдером HTML, CSS, JavaScripts, 5 страниц

Рассмотрим структуру файловой системы на примере FAT32.

Файловая структура FAT32

Устройства внешней памяти в системе FAT32 имеют не байтовую, а блочную адресацию. Запись информации в устройство внешней памяти осуществляется блоками или секторами.

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

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

Файловая система FAT32 имеет следующую структуру.

Нумерация кластеров, используемых для записи файлов, ведется с 2. Как правило, кластер №2 используется корневым каталогом, а начиная с кластера №3 хранится массив данных. Сектора, используемые для хранения информации, представленной выше корневого каталога, в кластеры не объединяются.
Минимальный размер файла, занимаемый на диске, соответствует 1 кластеру.

Загрузочный сектор начинается следующей информацией:

  • EB 58 90 – безусловный переход и сигнатура;
  • 4D 53 44 4F 53 35 2E 30 MSDOS5.0;
  • 00 02 – количество байт в секторе (обычно 512);
  • 1 байт – количество секторов в кластере;
  • 2 байта – количество резервных секторов.

Кроме того, загрузочный сектор содержит следующую важную информацию:

  • 0x10 (1 байт) – количество таблиц FAT (обычно 2);
  • 0x20 (4 байта) – количество секторов на диске;
  • 0x2С (4 байта) – номер кластера корневого каталога;
  • 0x47 (11 байт) – метка тома;
  • 0x1FE (2 байта) – сигнатура загрузочного сектора ( 55 AA ).

Сектор информации файловой системы содержит:

  • 0x00 (4 байта) – сигнатура ( 52 52 61 41 );
  • 0x1E4 (4 байта) – сигнатура ( 72 72 41 61 );
  • 0x1E8 (4 байта) – количество свободных кластеров, -1 если не известно;
  • 0x1EС (4 байта) – номер последнего записанного кластера;
  • 0x1FE (2 байта) – сигнатура ( 55 AA ).

Таблица FAT содержит информацию о состоянии каждого кластера на диске. Младшие 2 байт таблицы FAT хранят F8 FF FF 0F FF FF FF FF (что соответствует состоянию кластеров 0 и 1, физически отсутствующих). Далее состояние каждого кластера содержит номер кластера, в котором продолжается текущий файл или следующую информацию:

  • 00 00 00 00 – кластер свободен;
  • FF FF FF 0F – конец текущего файла.

Корневой каталог содержит набор 32-битных записей информации о каждом файле, содержащих следующую информацию:

  • 8 байт – имя файла;
  • 3 байта – расширение файла;

Корневой каталог содержит набор 32-битных записей информации о каждом файле, содержащих следующую информацию:

  • 8 байт – имя файла;
  • 3 байта – расширение файла;
  • 1 байт – атрибут файла:
  • 1 байт – зарезервирован;
  • 1 байт – время создания (миллисекунды) (число от 0 до 199);
  • 2 байта – время создания (с точностью до 2с):
  • 2 байта – дата создания:
  • 2 байта – дата последнего доступа;
  • 2 байта – старшие 2 байта начального кластера;
  • 2 байта – время последней модификации;
  • 2 байта – дата последней модификации;
  • 2 байта – младшие 2 байта начального кластера;
  • 4 байта – размер файла (в байтах).

В случае работы с длинными именами файлов (включая русские имена) кодировка имени файла производится в системе кодировки UTF-16. При этого для кодирования каждого символа отводится 2 байта. При этом имя файла записывается в виде следующей структуры:

  • 1 байт последовательности;
  • 10 байт содержат младшие 5 символов имени файла;
  • 1 байт атрибут;
  • 1 байт резервный;
  • 1 байт – контрольная сумма имени DOS;
  • 12 байт содержат младшие 3 символа имени файла;
  • 2 байта – номер первого кластера;
  • остальные символы длинного имени.

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

Работа с файлами в языке Си

Для программиста открытый файл представляется как последовательность считываемых или записываемых данных. При открытии файла с ним связывается поток ввода-вывода . Выводимая информация записывается в поток, вводимая информация считывается из потока.

Когда поток открывается для ввода-вывода, он связывается со стандартной структурой типа FILE , которая определена в stdio.h . Структура FILE содержит необходимую информацию о файле.

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

  • «r» — открыть файл для чтения (файл должен существовать);
  • «w» — открыть пустой файл для записи; если файл существует, то его содержимое теряется;
  • «a» — открыть файл для записи в конец (для добавления); файл создается, если он не существует;
  • «r+» — открыть файл для чтения и записи (файл должен существовать);
  • «w+» — открыть пустой файл для чтения и записи; если файл существует, то его содержимое теряется;
  • «a+» — открыть файл для чтения и дополнения, если файл не существует, то он создаётся.


Возвращаемое значение — указатель на открытый поток. Если обнаружена ошибка, то возвращается значение NULL .

Функция fclose() закрывает поток или потоки, связанные с открытыми при помощи функции fopen() файлами. Закрываемый поток определяется аргументом функции fclose() .

Возвращаемое значение: значение 0, если поток успешно закрыт; константа EOF , если произошла ошибка.

Чтение символа из файла:


Аргументом функции является указатель на поток типа FILE . Функция возвращает код считанного символа. Если достигнут конец файла или возникла ошибка, возвращается константа EOF .

Запись символа в файл:

Аргументами функции являются символ и указатель на поток типа FILE . Функция возвращает код считанного символа.

Функции fscanf() и fprintf() аналогичны функциям scanf() и printf() , но работают с файлами данных, и имеют первый аргумент — указатель на файл.

Функции fgets() и fputs() предназначены для ввода-вывода строк, они являются аналогами функций gets() и puts() для работы с файлами.


Символы читаются из потока до тех пор, пока не будет прочитан символ новой строки ‘\n’ , который включается в строку, или пока не наступит конец потока EOF или не будет прочитано максимальное символов. Результат помещается в указатель на строку и заканчивается нуль- символом ‘\0’ . Функция возвращает адрес строки.

Операционная система Microsoft Windows 3.1 для программиста

4.2. Функции Windows для работы с файлами

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

Открытие файлов

Для открытия файлов вы можете воспользоваться универсальной функцией OpenFile или более простой (но и более ограниченной) функцией _lopen.

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

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

Параметр lpszFileName является указателем на текстовую строку в кодировке ANSI, содержащую путь к файлу и закрытую двоичным нулем. В имени файла не допускается указывать символы шаблона, такие как «*» и «?».

Через параметр lpOpenStruct передается адрес структуры OFSTRUCT, которая заполняется информацией при первом открытии файла.

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

Константа Описание
OF_READ Файл открывается только для чтения
OF_WRITE Файл открывается только для записи
OF_READWRITE Файл открывается для чтения и записи
OF_SHARE_COMPAT Открытие файла в режиме совместимости. В этом режиме несколько приложений могут одновременно открыть файл, причем все эти приложения должны открывать файл в режиме совместимости
OF_SHARE_EXCLUSIVE Файл открывается в монопольном режиме. Для всех других приложений доступ к этому файлу на чтение и запись запрещен
OF_SHARE_DENY_WRITE После открытия файла к нему запрещается доступ со стороны других приложений на запись
OF_SHARE_DENY_READ После открытия файла к нему запрещается доступ со стороны других приложений на чтение
OF_SHARE_DENY_NONE Для открываемого файла не запрещается доступ к файлу ни на чтение, ни на запись
OF_PARSE Если указан этот флаг, функция OpenFile не выполняет никаких других действий, кроме заполнения структуры OFSTRUCT
OF_DELETE Уничтожение существующего файла
OF_VERIFY Если указан этот флаг, функция OpenFile сравнивает время и дату, записанную в структуре OFSTRUCT с временем и датой изменений указанного файла. Если обнаружено несоответствие, функция OpenFile возвращает значение HFILE_ERROR
OF_SEARCH Операционная система Windows выполняет поиск файла в каталогах даже в том случае, когда текстовая строка, указанная параметром lpszFileName, содержит полный путь к файлу
OF_PROMPT Если указан этот флаг, то в случае невозможности найти указанный файл Windows выдает диалоговую панель с предложением вставить в дисковод A: дискету с файлом. Этот флаг используется очень редко
OF_CANCEL Флаг OF_CANCEL используется в сочетании с флагом OF_PROMPT. Если он указан, то в описанную выше диалоговую панель будет добавлена кнопка «Cancel», позволяющая отменить открытие файла. Приложение получит в этом случае код ошибки, соответствующий ненайденному файлу, а пользователь — возможность выйти из безвыходного состояния, в которое он может попасть, не имея под рукой дискеты с нужным файлом
OF_CREATE Выполняется создание нового файла. Если указанный файл существует, он обрезается до нулевой длины
OF_EXIST При указании этого флага функция OpenFile вначале открывает файл, а затем сразу же его закрывает. Эта бесполезная на первый взгляд операция может быть использована для того чтобы убедиться в существовании указанного файла на диске
OF_REOPEN Этот флаг используется при повторном открытии файла на основе информации, хранящейся в структуре OFSTRUCT

Когда функция OpenFile вызывается в первый раз для открытия файла, она заполняет структуру OFSTRUCT , описанную в файле windows.h следующим образом:

Поле cBytes содержит размер самой структуры OFSTRUCT в байтах.

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

Если при открытии файла произошла ошибка, в поле nErrCode записывается код ошибки. Возможные значения для кода ошибки приведены в приложении 1.

Поле reserved зарезервировано и не должно использоваться.

В поле szPathName находится полный путь к файлу в кодировке OEM.

Если функция OpenFile показалась вам слишком сложной в использовании, в ряде случаев для открытия файла вы сможете ограничиться функцией _lopen :

Функция возвращает идентификатор открытого файла или HFILE_ERROR при ошибке.

Параметр lpszFileName, так же как и для функции OpenFile, является указателем на текстовую строку в кодировке ANSI, содержащую путь к файлу и закрытую двоичным нулем. В имени файла не допускается указывать символы шаблона, такие как «*» и «?».

Параметр fuOpenMode определяет режим, в котором открывается файл. Приведем список возможных значений для этого параметра.

Константа Описание
READ Файл открывается только для чтения
WRITE Файл открывается только для записи
READWRITE Файл открывается для чтения и записи
OF_SHARE_COMPAT Открытие файла в режиме совместимости. В этом режиме несколько приложений могут одновременно открыть файл, причем все эти приложения должны открывать файл в режиме совместимости
OF_SHARE_EXCLUSIVE Файл открывается в монопольном режиме. Для всех других приложений доступ к этому файлу на чтение и запись запрещен
OF_SHARE_DENY_WRITE После открытия файла к нему запрещается доступ со стороны других приложений на запись
OF_SHARE_DENY_READ После открытия файла к нему запрещается доступ со стороны других приложений на чтение
OF_SHARE_DENY_NONE Для открываемого файла не запрещается доступ к файлу ни на чтение, ни на запись

Если вам надо открыть файл в каталоге, где находится сама операционная система Windows или в системном каталоге Windows, воспользуйтесь функциями, соответственно, GetWindowsDirectory и GetSystemDirectory.

Функция GetWindowsDirectory позволяет определить расположение каталога, в который была установлена операционная система Windows:

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

С помощью параметра cbSysPath необходимо указать размер буфера в байтах.

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

Для определения пути к системному каталогу Windows предназначена функция GetSystemDirectory :

Назначение параметров этой функции аналогично назначению параметров функции GetWindowsDirectory.

Так как системный каталог Windows может находиться на сервере, приложение не должно пытаться создавать или изменять файлы в этом каталоге. Как правило, пользователь не имеет права записи в системный каталог Windows.

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

В составе операционной системы Windows версии 3.1 имеется DLL-библиотека commdlg.dll, экспортирующая среди прочих две функции, очень удобные для организации пользовательского интерфейса при открытии файлов. Это функции GetOpenFileName и GetSaveFileName . Мы уже пользовались этими функциями в приложениях OEM2ANSI и OEM3ANSI.

Функция GetOpenFileName выводит на экран стандартную или измененную приложением диалоговую панель «Open», позволяющую выбрать файл (рис. 4.1).

Рис. 4.1. Диалоговая панель «Open»

Функция GetSaveFileName выводит стандартную или измененную приложением диалоговую панель «Save As. » (рис. 4.2).

Рис. 4.2. Диалоговая панель «Save As. «

Внешний вид этих диалоговых панелей определяется структурой типа OPENFILENAME , определенной в файле commdlg.h (этот файл находится в каталоге include системы разработки Borland C++ или Microsoft Visual C++):

Адрес структуры передается функциям GetOpenFileName и GetSaveFileName в качестве параметра lpofn:

Обе функции возвращают ненулевое значение, если пользователь сделал выбор файла, и ноль, если он отказался от выбора, нажав кнопку «Cancel» или выбрав строку «Close» из системного меню диалоговой панели. Нулевое значение возвращается также при возникновении ошибки.

В результате выбора некоторые поля структуры будут заполнены информацией о выбранном файле.

Опишем назначение отдельных полей структуры OPENFILENAME.

lStructSize

Поле lStructSize перед вызовом функций должно содержать размер структуры OPENFILENAME в байтах.

Flags

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

Флаг Описание
OFN_ALLOWMULTISELECT Разрешается выбор нескольких файлов одновременно. Если указан этот флаг, после выбора поле lpstrFile будет указывать на буфер, заполненный именами выбранных файлов (или путями к выбранным файлам), разделенными пробелом
OFN_CREATEPROMPT При использовании этого флага если указанный файл не существует, создается диалоговая панель, в которой предлагается создать файл. Этот флаг устанавливается автоматически при использовании флагов OFN_PATHMUSTEXIST и OFN_FILEMUSTEXIST
OFN_ENABLEHOOK Разрешается использовать функцию фильтра, адрес которой указан в поле lpfnHook
OFN_ENABLETEMPLATE Если указан этот флаг, для создания диалоговой панели Windows будет использовать шаблон, определяемый содержимым полей hInstance и lpTemplateName
OFN_ENABLETEMPLATEHANDLE При использовании этого флага поле hInstance используется для идентификации блока памяти, содержащий предварительно загруженный шаблон диалоговой панели. В этом случае содержимое поля lpTemplateName игнорируется
OFN_EXTENSIONDIFFERENT Устанавливается после возвращения из функции и указывает, что расширение возвращенного имени файла отличается от заданного в поле lpstrDefExt. Этот флаг не устанавливается, если перед вызовом функции в поле lpstrDefExt было записано значение NULL, или если файл не имеет расширения имени
OFN_FILEMUSTEXIST Можно выбирать только имена тех файлов, которые существуют. Если в поле «File Name» диалоговой панели набрать имя несуществующего файла, на экране появится диалоговая панель с предупреждающим сообщением
OFN_HIDEREADONLY Убрать переключатель «Read Only»
OFN_NOCHANGEDIR Для выбора используется каталог, который был текущим при вызове функции
OFN_NOREADONLYRETURN Выбранные файлы не могут иметь атрибут «только чтение» или располагаться в защищенном от записи каталоге
OFN_NOTESTFILECREATE Перед завершением работы диалоговой панели создание файла не выполняется. Не выполняются и проверки на переполнение диска, защиту записи или наличие доступа в сети
OFN_NOVALIDATE В возвращаемом имени файла могут присутствовать неразрешенные символы
OFN_OVERWRITEPROMPT Используется для диалоговой панели «Save As. «. Если выбранный файл существует, на экран выводится диалоговая панель с предупреждением
OFN_PATHMUSTEXIST Можно вводить только существующие пути к файлам
OFN_READONLY После вызова функции переключатель «Read Only» будет находиться во включенном состоянии
OFN_SHAREWARE Флаг устанавливается после возвращения из функции и указывает, что при вызове функции OpenFile произошла ошибка при совместном доступе к файлу в сети
OFN_SHOWHELP Если указан этот флаг, в диалоговой панели будет создана кнопка «Help». Если указан этот флаг, поле hwndOwner не должно содержать значение NULL
Илон Маск рекомендует:  Mpeg для чайников

hwndOwner

Поле hwndOwner должно содержать идентификатор окна, создавшего диалоговую панель. Можно указать значение NULL, при этом диалоговая панель не будет иметь окно-владельца. В этом случае нельзя использовать флаг OFN_SHOWHELP.

hInstance

Поле hInstance используется перед вызовом функции для идентификации блока памяти, содержащего шаблон диалоговой панели. Содержимое поля игнорируется в том случае, если не указаны флаги OFN_ENABLETEMPLATE или OFN_ENABLETEMPLATEHANDLE.

lpstrFilter

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

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

Первая строка в паре строк описывает название фильтра, например «Text Files» (текстовые файлы), во второй строке пары через символ «;» перечисляются возможные шаблоны для имен файлов.

lpstrCustomFilter

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

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

Первая строка в паре строк описывает название фильтра, например «Text Files» (текстовые файлы), во второй строке пары через символ «;» перечисляются возможные шаблоны для имен файлов.

Если поле lpstrFilter содержит NULL, используется фильтр lpstrCustomFilter.

nMaxCustFilter

Определяет размер буфера в байтах, указанного в поле lpstrCustomFilter. Размер этого буфера должен быть не меньше 40 байт.

nFilterIndex

Поле nFilterIndex определяет номер пары строк, используемой для фильтра, указанного в поле lpstrFilter. Если в качестве значения для этого поля указать 0, будет использован фильтр, определенный в поле lpstrCustomFilter.

lpstrFile

Поле lpstrFile должно содержать адрес текстовой строки, в которую будет записан полный путь к выбранному файлу.

Если по указанному выше адресу перед вызовом функции GetOpenFileName или GetSaveFileName расположить текстовую строку, содержащую путь к файлу, этот путь будет выбран по умолчанию сразу после отображения диалоговой панели «Open» или «Save As. «.

nMaxFile

Поле nMaxFile должно содержать размер в байтах буфера, расположенного по адресу, указанному в поле lpstrFile.

Размер этого буфера должен быть достаточным для записи полного пути к файлу. Файловая система MS-DOS допускает использование для указания пути к файлу не более 128 символов.

lpstrFileTitle

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

nMaxFileTitle

Поле nMaxFileTitle должно содержать размер указанного выше буфера.

lpstrInitialDir

Поле lpstrInitialDir позволяет указать начальный каталог, который будет выбран для поиска файла сразу после отображения диалоговой панели «Open». Для того чтобы начать поиск в текущем каталоге, в это поле следует записать значение NULL.

lpstrTitle

С помощью этого поля можно определить заголовок диалоговой панели, появляющейся при вызове функции. Если это поле содержит NULL, будут использованы стандартные заголовки «Open» и «Save As. «.

nFileOffset

После возврата из функции это поле содержит смещение первого символа имени файла относительно начала буфера lpstrFile.

nFileExtension

После возврата из функции это поле содержит смещение первого символа расширения имени файла относительно начала буфера lpstrFile.

lpstrDefExt

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

lCustData

Значение, передаваемой функции фильтра через параметр lParam.

lpfhHook

Указатель на функцию фильтра, обрабатывающую сообщения для диалоговой панели. Функция фильтра будет вызываться только в том случае, если указан флаг OFN_ENABLEHOOK. Если фильтр не обрабатывает сообщение, он должен вернуть нулевое значение. Если же он вернет значение, отличное от нуля, стандартная функция диалога не будет обрабатывать сообщение, которое уже было обработано функцией фильтра.

lpTemplatename

Идентификатор ресурса, содержащего шаблон диалоговой панели, используемого вместо имеющегося в DLL-библиотеке commdlg.dll. Для ссылки на ресурс можно использовать макрокоманду MAKEINTRESOURCE. Для использования альтернативного шаблона (и, соответственно, данного поля), в поле Flags следует установить флаг OFN_ENABLETEMPLATE.

Закрытие файлов

Теперь о том, как закрыть файл. Для закрытия файла вы должны использовать функцию _lclose :

Идентификатор закрываемого файла передается функции через параметр hf.

Если файл закрыт успешно, функция _lclose возвращает нулевое значение. При ошибке возвращается значение HFILE_ERROR.

Создание файлов

Для создания файлов вы можете использовать как универсальную функцию OpenFile, описанную нами ранее, так и более простую функцию _lcreat :

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

С помощью параметра fuAttribute можно определить атрибуты создаваемого файла:

Значение атрибута Описание
Нормальный файл, для которого разрешено выполнение операций чтения и записи
1 Этот файл можно открыть только для чтения
2 Скрытый файл
3 Системный файл

Если указанный первым параметром файл не существует, функция _lcreat создает его и открывает для записи, возвращая идентификатор файла. Если файл существует, он обрезается до нулевой длины и затем открывается для чтения и записи.

Чтение и запись

Для выполнения операций чтения и записи в программном интерфейсе операционной системы Windows версии 3.1 предусмотрены четыре функции: _lread, _hread, _lwrite, _hwrite.

Функция _lread предназначена для чтения из открытого файла:

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

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

Прочитанные данные будут записаны в буфер hpvBuffer, имеющий размер cbBuffer байт. Этот буфер можно получить динамически, вызывав, например, функцию GlobalAlloc или LocalAlloc. Размер буфера не должен превышать 65534 байт.

В программном интерфейсе операционной системы Windows версии 3.1 появилась функция _hread , с помощью которой можно выполнять чтение из файла блоков практически любого размера:

Так же как и функция _lread, функция _hread возвращает количество байт данных, прочитанных из файла. Возвращенное значение может быть меньше затребованного в параметре cbBuffer, если в процессе чтения был достигнут конец файла. При ошибке функция возвращает значение HFILE_ERROR.

Вы можете с помощью функции GlobalAlloc заказать для функции _hread буфер размером, большим 64 Кбайт.

С помощью функции _lwrite вы можете выполнить запись данных в файл:

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

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

Если вам надо писать в файл блоки, имеющие размер больше 64 Кбайт, воспользуйтесь функцией _hwrite , которая впервые появилась в программном интерфейсе Windows версии 3.1:

Назначение параметров функции аналогично назначению параметров функции _lwrite. Функция возвращает количество байт данных, записанных в файл, или значение HFILE_ERROR при ошибке.

Позиционирование

Для выполнения операции позиционирования внутри файла приложения Windows могут использовать функцию _llseek :

Функция _llseek перемещает указатель текущей позиции в файле на lOffset байт, причем направление смещения зависит от значения параметра nOrigin следующим образом:

Значение Описание
SEEK_SET Указатель текущей позиции в файле перемещается на lOffset байт от начала файла
SEEK_CUR Указатель текущей позиции в файле перемещается на lOffset байт от текущей позиции
SEEK_END Указатель текущей позиции в файле перемещается на lOffset байт от конца файла

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

Функция возвращает новое значение текущей позиции от начала файла или HFILE_ERROR при ошибке.

Определение типа устройства ввода/вывода

Иногда приложению требуется определить тип и расположение используемого дискового устройства ввода/вывода. Для этого можно воспользоваться функцией GetDriveType :

Параметр DriveNumber определяет номер диска, для которого требуется определить тип и расположение (0 соответствует устройству A:, 1 — B:, и т. д.).

Функция может вернуть 0 при ошибке или одно из следующих значений:

Значение Описание
DRIVE_REMOVABLE Сменный диск
DRIVE_FIXED Несменный диск
DRIVE_REMOTE Удаленный диск, расположен на другой машине в сети

Использование стандартной библиотеки транслятора

Для работы с файлами в приложениях Windows вы можете использовать функции из стандартной библиотеки транслятора C или C++, такие как read , fread , write , fwrite , lseek , fstat , tell , close .

Можно также использовать функции потокового ввода/вывода , если преобразовать идентификатор файла в указатель на структуру FILE при помощи функции fdopen . Для того чтобы закрыть такой файл следует воспользоваться функцией fclose .

Перечисленные выше функции были описаны в третьей книге первого тома «Библиотеки системного программиста» в главе «Файловая система DOS».

Проверка присутствия share.exe

Как мы уже говорили, в многозадачной среде утилита MS-DOS share.exe приобретает особое значение, выступая координатором доступа работающих параллельно приложений к файлам. Для того чтобы приучить забывчивых или беспечных пользователей не удалять команду загрузки этой утилиты из файла autoexec.bat вы можете сделать так, чтобы ваше приложение выдавала предупреждающее сообщение, если утилита share.exe не загружена.

Однако проблема не так проста, как кажется. Для того чтобы определить, загружена ли утилита share.exe , программы MS-DOS могли воспользоваться функцией 1000h прерывания INT 2Fh. Эта функция используется самой утилитой share.exe для предотвращения повторной загрузки.

Но вызвав эту функцию из приложения Windows, вы можете, к своему огорчению, убедиться, что она всегда сообщает о том, что share.exe загружена в память, даже если вы вообще стерли файл share.exe с диска. Это сделано специально, но не для того чтобы затруднить обнаружение share.exe, а для того чтобы предотвратить ее загрузку из виртуальной машины MS-DOS, работающей в среде Windows.

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

В качестве такой функции проще всего использовать блокирование участка файла (функция 0x5c прерывания INT 21h). Как мы уже говорили, Windows выполняет эмуляцию большого числа функций прерывания MS-DOS, позволяя приложениям Windows обращаться к этим функциям.

В листинге 4.1 приведены исходные тексты приложения ISSHARE, которое проверяет присутствие share.exe, выполняя попытку заблокировать первый байт созданного временного файла.

Листинг 4.1. Файл isshare/isshare.cpp

Функция WinMain проверяет, загружена ли утилита share.exe, вызывая функцию ShareLoaded, определенную в приложении.

Эта функция может вернуть 0, 1 или -1. Если функция вернула 0, share.exe не загружена. Если функция вернула -1, произошла ошибка при создании временного файла. И, наконец, если функция ShareLoaded вернула 1, share.exe загружена.

Для создания временного файла используется функции GetTempFileName и _lcreat. Первая из этих двух функций получает имя временного файла, вторая — создает и открывает временный файл.

Для выполнения блокировки приложение вызывает функцию MS-DOS, пользуясь известной вам функцией intdos.

Если утилита share.exe установлена и блокировка файла выполнена успешно, функция ShareLoaded разблокирует файл, вызывая функцию MS-DOS с кодом 0x5c еще раз, но с другим значением регистра AL.

В любом случае перед возвратом из функции временный файл закрывается функцией _lclose и затем удаляется функцией OpenFile.

Файл определения модуля для приложения ISSHARE приведен в листинге 4.2.

Функции библиотеки C — freopen ()

описание

C библиотечные функцииFILE * freopen (Const символ * имя файла , сопзЬ сЬаг * Режим, FILE * поток) в новый поток файла потока имени файла , связанного с данным набором открытым, при закрытии потока старых файлов.

заявление

Здесь freopen () объявление функции.

параметры

  • Имя файла — Это C строка , содержащая имя файла , который вы хотите открыть.
  • Режим — это строка , содержащая С в режим доступа к файлу, режим выглядит следующим образом :
模式 描述
«r» 打开一个用于读取的文件。该文件必须存在。
«w» 创建一个用于写入的空文件。如果文件名称与已存在的文件相同,则会删除已有文件的内容,文件被视为一个新的空文件。
«a» 追加到一个文件。写操作向文件末尾追加数据。如果文件不存在,则创建文件。
«r+» 打开一个用于更新的文件,可读取也可写入。该文件必须存在。
«w+» 创建一个用于读写的空文件。
«a+» 打开一个用于读取和追加的文件。
  • Поток — это указатель на FILE указатель на объект, идентификатор объекта файл должен быть повторно открыть поток.

Возвращаемое значение

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

примеров

Следующий пример демонстрирует freopen () функция используется.

Давайте скомпилировать и запустить эту программу, которая будет посылать следующие строки на стандартный вывод STDOUT, потому что сначала мы не включить в стандартный вывод:

После вызоваfreopen (), он будет связан на стандартный вывод STDOUT файла file.txt,будем ли мы в том, что написано записывается в стандартный вывод STDOUT file.txt, вы будете иметь следующий файл file.txt содержание.

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

Понравилась статья? Поделиться с друзьями:
Кодинг, CSS и SQL