- Работа с файлами в си ввод и вывод в файл в си
- Работа с файлами в си
- Считывание информации из текстового файла в Си
- Оператор fscanf()
- Построковое считывание информации из файла в СИ.Функция fgets ( )
- Запись информации в текстовый файл в Си
- Язык си чтение файла
- Ввод данных из файла и вывод в файл
- Открытие и закрытие файлов
- Чтение из текстового файла и запись в него
- fscanf()
- fgets()
- getc() или fgetc()
- Запись в текстовый файл
- Чтение из двоичного файла и запись в него
- Работа с файлами в C
- Как работать с файлами
- Опции-параметры для открытия файлов
- Запись в текстовый файл
- Позиционирование указателя при записи файла
- Основные функции для работы с файлами в языке Си
- Открытие и закрытие файлового потока
- Чтение из файлов
- Запись в файл
- Считывание русских символов из файла
- Отличие работы с потоками в Си от других языков
- Заключение
- Работа с файлами
- Файловая структура FAT32
- Работа с файлами в языке Си
- Видео
Работа с файлами в си ввод и вывод в файл в си
Работа с файлами в си
Считывание информации из текстового файла в Си
Чтобы можно было считывать русские символы из файла, необходимо настроить работу с Кириллицей с помощью команды
setlocale(LC_ALL, «Russian»);
При этом необходимо в начале программы подключить #include
Оператор fscanf()
Для считывания слова из файла в си используется команда fscanf(). Эта команда аналогична команде ввода информации с клавиватуры в си scanf() только первый параметр это указатель на файл
fscanf(указатель на файл,»%формат ввода данных1% форматввода данных2…»,&перменная1,&переменная2…);
Например команда
fscanf(fin,»%d%d%d»,&a,&b,&c);
считает из файла, который привязан к указателю на файл fin строку из трех целочисленных переменных
Разберем пример программы, которая считывает из текстового файла data.txt в которые записаны три столбца цифр информацию и записывает ее в массивы. Для каждого столбца информации свой массив. Подробно о работе с массивами в Си.
#include
#include
main()
< int a[10];
int b[10];
int c[10];
int i;
// определяем указатель на файл
FILE *fin;
// открываем файл на чтение
fin = fopen(«C:\\Users\\user\\Desktop\\data.txt», «r»);
// построчное считывание из файла
for (i=0;i
Построковое считывание информации из файла в СИ.Функция fgets ( )
Запись информации в текстовый файл в Си
Для записи данных в файл в Си, необходимо открыть файл в режиме записи
Имя указателя на файл= fopen(«путь к файлу», «w»);
Для записи в строку текстового файла используется команда fprnitf(), которая аналогична команде printf() вывод на экран в си только первый параметр это указатель на файл
fprintf (имя указателя на файл,”%формат ввода”, переменные);
Например запись в файл out.txt значение переменной а
a=10;
fout = fopen(«C:\\Users\\user\\Desktop\\out.txt», «w»);
fprintf (fout,”%d”, a);
Пример программы на си которая запрашивает два числа и записывает в файл out.txt оба эти числа и их сумму
main()
< int a;
int b;
int c;
FILE *fout;
fout = fopen(«C:\\Users\\user\\Desktop\\out.txt», «w»);
printf («введите первое число \n»);
scanf(«%d», &a);
printf («введите второе число \n»);
scanf(«%d», &b);
c=a+b;
fprintf(fout,»%d %d %d»,a,b,c);
getch();
fclose(fout);
>
Язык си чтение файла
Доступ к диску (чтение/запись) гораздо (на несколько порядков) медленнее, чем доступ к данным в оперативной памяти. Кроме того, если мы читаем или записываем файл при помощи системных вызовов маленькими порциями (по 1-10 символов)
Еще одной проблемой является то, что системные вызовы работают с файлом как с неструктурированным массивом байт; тогда как человеку часто удобнее представлять, что файл поделен на строки, содержащие читабельный текст, состоящий лишь из обычных печатных символов (текстовый файл).
Небезызвестная директива #include включает в нашу программу файл с объявлением форматов данных и констант, используемых этой библиотекой.
Библиотеку stdio можно назвать библиотекой буферизованного обмена, а также библиотекой работы с текстовыми файлами (т.е. имеющими разделение на строки), поскольку для оптимизации обменов с диском (для уменьшения числа обращений к нему и тем самым сокращения числа системных вызовов) эта библиотека вводит буферизацию, а также предоставляет несколько функций для работы со строчно-организованными файлами.
Предусмотрено несколько стандартных структур FILE, указатели на которые называются stdin, stdout и stderr и связаны с дескрипторами 0, 1, 2 соответственно (стандартный ввод, стандартный вывод, стандартный вывод ошибок). Напомним, что эти каналы открыты неявно (автоматически) и, если не перенаправлены, связаны с вводом с клавиатуры и выводом на терминал.
При чтении символа getc выдает ее первый байт.
Открыть файл, создать буфер: По умолчанию fopen() использует для creat коды доступа accessmode равные 0666 (rwrw-rw-).
Соответствие аргументов fopen и open:
Для r, r+ файл уже должен существовать, в остальных случаях файл создается, если его не было.
По указателю fp можно узнать дескриптор файла: Это макроопределение просто выдает поле из структуры FILE. Обратно, если мы открыли файл open-ом, мы можем ввести буферизацию этого канала: (здесь надо вновь указать КАК мы открываем файл, что должно соответствовать режиму открытия open-ом). Теперь можно работать с файлом через fp, а не fd.
В приложении имеется текст, содержащий упрощенную реализацию главных функций из библиотеки stdio.
Функция ungetc(c,fp) «возвращает» прочитанный байт в файл. На самом деле байт возвращается в буфер, поэтому эта операция неприменима к небуферизованным каналам. Возврат соответствует сдвигу указателя чтения из буфера (который увеличивается при getc()) на 1 позицию назад. Вернуть можно только один символ подряд (т.е. перед следующим ungetc-ом должен быть хоть один getc), поскольку в противном случае можно сдвинуть указатель за начало буфера и, записывая туда символ c, разрушить память программы.
Очень часто делают ошибку в функции fputc, путая порядок ее аргументов. Так ничего не стоит написать: Запомните навсегда! указатель файла идет вторым! Существует также макроопределение Оно ведет себя как и функция fputc, но не может быть передано в качестве аргумента в функцию:
Отметим еще, что putchar и getchar это тоже всего лишь макросы
Для чтения данных по формату используются функции семейства
Функции fprintf и fscanf являются наиболее мощным средством работы с текстовыми файлами (содержащими изображение данных в виде печатных символов).
Текстовые файлы (имеющие строчную организацию) хранятся на диске как линейные массивы байт. Для разделения строк в них используется символ ‘\n‘. Так, например, текст хранится как массив
При выводе на экран дисплея символ \n преобразуется драйвером терминалов в последовательность \r\n, которая возвращает курсор в начало строки (‘\r‘) и опускает курсор на строку вниз (‘\n‘), то есть курсор переходит в начало следующей строки.
Все нетекстовые файлы в MS DOS надо открывать именно так, иначе могут произойти разные неприятности. Например, если мы программой копируем нетекстовый файл в текстовом режиме, то одиночный символ \n будет считан в программу как \n, но записан в новый файл как пара \r\n. Поэтому новый файл будет отличаться от оригинала (что для файлов с данными и программ совершенно недопустимо!).
Задание: напишите программу подсчета строк и символов в файле. Указание: надо подсчитать число символов ‘\n‘ в файле и учесть, что последняя строка файла может не иметь этого символа на конце. Поэтому если последний символ файла (тот, который вы прочитаете самым последним) не есть ‘\n‘, то добавьте к счетчику строк 1.
Напишите программу подсчета количества вхождений каждого из символов алфавита в файл и печатающую результат в виде таблицы в 4 колонки. (Указание: заведите массив из 256 счетчиков. Для больших файлов счетчики должны быть типа long).
Почему вводимый при помощи функций getchar() и getc(fp) символ должен описываться типом int а не char?
В MS DOS же в текстовых файлах признак конца (EOF) хранится явно и обозначается символом CTRL/Z. Поэтому, если программным путем записать куда-нибудь в середину файла символ CTRL/Z, то некоторые программы перестанут «видеть» остаток файла после этого символа!
Напишите программу, которая запрашивает ваше имя и приветствует вас. Для ввода имени используйте стандартные библиотечные функции В чем разница?
Функция fgets() контролирует длину строки: если строка на входе окажется длиннее, чем slen символов, то остаток строки не будет прочитан в буфер s, а будет оставлен «на потом». Следующий вызов fgets прочитает этот сохраненный остаток. Кроме того fgets, в отличие от gets, не обрубает символ ‘\n‘ на конце строки, что доставляет нам дополнительные хлопоты по его уничтожению, поскольку в Си «нормальные» строки завершаются просто ‘\0‘, а не «\n\0«.
Фрагмент для обрубания символа перевода строки может выглядеть еще так:
*** При выполнении вызова завершения программы exit(); все открытые файлы автоматически закрываются.
***** Управляющие символы имеют следующие значения:
© Copyright А. Богатырев, 1992-95
Си в UNIX
Ввод данных из файла и вывод в файл
Открытие и закрытие файлов
До этого при вводе-выводе данных мы работали со стандартными потоками — клавиатурой и монитором. Теперь рассмотрим, как в языке C реализовано получение данных из файлов и запись их туда. Перед тем как выполнять эти операции, надо открыть файл и получить доступ к нему.
В языке программирования C указатель на файл имеет тип FILE и его объявление выглядит так:
С другой стороны, функция fopen() открывает файл по указанному в качестве первого аргумента адресу в режиме чтения («r»), записи («w») или добавления («a») и возвращает в программу указатель на него. Поэтому процесс открытия файла и подключения его к программе выглядит примерно так:
Примечание. В случае использования относительной адресации текущим/рабочим каталогом в момент исполнения программы должен быть тот, относительно которого указанный относительный адрес корректен. Место нахождения самого исполняемого файла не важно.
При чтении или записи данных в файл обращение к нему осуществляется посредством файлового указателя (в данном случае, myfile).
Объявление функции fopen() содержится в заголовочном файле stdio.h, поэтому требуется его подключение. Также в stdio.h объявлен тип-структура FILE.
В программе может быть открыт не один файл. В таком случае каждый файл должен быть связан со своим файловым указателем. Однако если программа сначала работает с одним файлом, потом закрывает его, то указатель можно использовать для открытия второго файла.
Чтение из текстового файла и запись в него
fscanf()
Возвращает количество удачно считанных данных или EOF. Пробелы, символы перехода на новую строку учитываются как разделители данных.
Допустим, у нас есть файл содержащий такое описание объектов:
Тогда, чтобы считать эти данные, мы можем написать такую программу:
В данном случае объявляется структура и массив структур. Каждая строка из файла соответствует одному элементу массива; элемент массива представляет собой структуру, содержащую строковое и два числовых поля. За одну итерацию цикл считывает одну строку. Когда встречается конец файла fscanf() возвращает значение EOF и цикл завершается.
fgets()
Функция fgets() аналогична функции gets() и осуществляет построчный ввод из файла. Один вызов fgets() позволят прочитать одну строку. При этом можно прочитать не всю строку, а лишь ее часть от начала. Параметры fgets() выглядят таким образом:
В этой программе в отличие от предыдущей данные считываются строка за строкой в массив arr. Когда считывается следующая строка, предыдущая теряется. Функция fgets() возвращает NULL в случае, если не может прочитать следующую строку.
getc() или fgetc()
Функция getc() или fgetc() (работает и то и другое) позволяет получить из файла очередной один символ.
Приведенный в качестве примера код выводит данные из файла на экран.
Запись в текстовый файл
Также как и ввод, вывод в файл может быть различным.
Ниже приводятся примеры кода, в которых используются три способа вывода данных в файл.
Запись в каждую строку файла полей одной структуры:
Пример посимвольного вывода:
Чтение из двоичного файла и запись в него
С файлом можно работать не как с последовательностью символов, а как с последовательностью байтов. В принципе, с нетекстовыми файлами работать по-другому не возможно. Однако так можно читать и писать и в текстовые файлы. Преимущество такого способа доступа к файлу заключается в скорости чтения-записи: за одно обращение можно считать/записать существенный блок информации.
При открытии файла для двоичного доступа, вторым параметром функции fopen() является строка «rb» или «wb».
Тема о работе с двоичными файлами достаточно сложная, для ее изучения требуется отдельный урок. Здесь будут отмечены только особенности функций чтения-записи в файл, который рассматривается как поток байтов.
Функции fread() и fwrite() принимают в качестве параметров:
Эти функции возвращают количество успешно прочитанных или записанных данных. Т.е. можно «заказать» считывание 50 элементов данных, а получить только 10. Ошибки при этом не возникнет.
Пример использования функций fread() и fwrite() :
Здесь осуществляется попытка чтения из первого файла 50-ти символов. В n сохраняется количество реально считанных символов. Значение n может быть равно 50 или меньше. Данные помещаются в строку. То же самое происходит со вторым файлом. Далее первая строка присоединяется ко второй, и данные сбрасываются в третий файл.
Работа с файлами в C
В языке Си, файлы рассматриваются как место, куда можно сохранять информацию и читать данные, выводя их в другой файл, в консоль и другие места. Язык C предоставляет все необходимое, для выполнения операций с файлами. Запись или чтение из файла является потоком байтов. Прежде, чем осуществлять какую-либо манипуляцию с файлом, необходимо открыть поток.
Как работать с файлами
Для открытия потока передачи байтов следует писать следующую конструкцию:
FILE * переменная fopen(имя файла, режим открытия);
Если открытый файл уже не нужен, то его следует закрыть. В противном случае он будет потреблять лишнюю память, что может сказаться на производительности программы. Для закрытия файла применяется функция fclosе(переменная потока). Параметр функции указывает на переменную, в которую был сохранен открытый поток. Если поток был успешно закрыт, то функция возвращает 0, в противном случае EOF, указывающее на ошибку.
Пример открытия и закрытия потока:
int main(void)
<
FILE * f = fopen(«D:\text.txt», «w»); \\ Доступ к файлу, который находится по адресу D:\text.txt c параметром «W», который указывает на запись.
fclose(f); \\ Удаление потока
return 0;
>
Открытие потоков может сопровождаться ошибками. К примеру, при открытии файла для чтения, окажется, что такового не существует. Может быть недостаточно памяти для открытия файла и тому подобное. Если ошибка присутствует, то функция fopen() вернет NULL. Поэтому, чтобы такого не происходило, можно обработать ошибку с помощью функции perror.
Пример проверки на ошибку:
int main(void)
<
FILE * f; \\ Объявление переменной типа FILE
if((f= fopen(«D:\text25.txt», «r»))==NULL) \\ Проверка на наличие ошибки при открытии потока.
<
perror(«Error:»); Если есть ошибка, то будет выведен ее текст, в нашем случае это «Error No such file or directory».
exit(0); \\Принудительный выход из программы.
>
fclose(f); \\ Если файл открыт, то функция тут же его закроет.
return 0;
>
Для вывода ошибки в консоль, применяется функция perror(string), которая в качестве параметра принимает текст ошибки. В нашем примере не имеет смысла продолжать выполнение программы, поэтому ее принудительно останавливают с помощью функции exit(0).
Текст ошибки из параметра функции perror сопровождается и сообщением компилятора в виде No such file or directory, которое говорит о отсутствия такого файла в указанной директории. Однако некоторые параметры функции fopen позволяют создать несуществующий файл. Если файл с конкретным именем не находится, то он будет создан заново.
Опции-параметры для открытия файлов
Второй параметр функции fopen задает ограничения на действия открытого файла. От режима зависит как файл может быть обработан. Каждый режим представляет собой символ или их набор. Существуют следующие режимы открытия файловых потоков в языке Си:
Те же параметры применяются и для текстовых файлов, только без символа «b». Режимы задаются чтобы расширить возможности манипуляций с файлом и ограничить их до чтения или только записи. Также режимы задают формат файла — бинарный или текстовый. Неправильно установленный режим может привести либо к ошибке, либо к некорректной интерпретации файла.
Запись в текстовый файл
Для записи символов или строки в текстовый файл используется функция fputs(). Синтаксис данной функции следующий: int fputs( const char ch, FILE f); Здесь первый параметр ch принимает записываемую строку или символ. Второй параметр указывает на открытый файловый поток. Если при записи произошла ошибка, то функция возвращает значение ошибки EOF.
Пример записи теста в файл:
int main(void)
<
char * mes = «Hello, my name is Vova»; \\Сохраняем строку для записи в файл
char * fName = «D://text5.txt»; \\Сохраняем путь к файлу
char c[256];
FILE * f;
if((f= fopen(fName, «w»))==NULL) \\Если возникла ошибка при открытии файла, то вывести сообщение «Error» и выйти из программы
<
perror(«Error»);
return 1;
>
fputs(mes, f); \\ Запись в файл строки в переменной mes
Так как в данном примере был использован режим открытия «W», то нам открывается пустой файл для записи. Если после выполнения данного кода открыть файл text5.txt, то в его содержании будет строка «Hello, my name is Vova».
Позиционирование указателя при записи файла
Режим «r» или «w» устанавливает каретку записи в начало файла. Режим «a» устанавливает каретку в конец имеющихся данных. Таким образом первый вариант перезаписывает файл, второй дописывает. При записи или чтении каретка передвигается на позицию, равную числу прочитанных или записанных байтов, или символов.
Однако часто необходимо выполнять поток байтов с конкретной позиции в файле, к примеру, со средины или с 53-й позиции. Для этого необходимо воспользоваться функцией fseek(), которая перемещает каретку в указанную позицию.
У данной функции следующий синтаксис: fseek(файл, количество байтов для смещения, начальная позиции);
Пояснение к функции:
Пример использования функции fseek():
int main(void) <
int i; \\ Переменная для сохранения символов в цикле
char * str = «Hello»; \\ Первая строка записываемая в файл
char * final_str; \\ Строка для дописывания в файл
File * f = fopen(«text.txt», w);
fputs(str, f); \\ Записываем первую строку в файл
fseek(f, 6, SEEK_SET); \\ Устанавливаем каретку на 6-ю позицию
fputs(«World!», f); \\ С шестой позиции записываем в файл строку «World!»
fseek(f, 0, SEEK_SET); \\ Устанавливаем позицию каретки в начало
while ((i = getc(f))!=EOF) \\ Получаем каждый символ файла и сохраняем его в переменную «final_str»
<
*final_str +=(char *)i;
>
printf(«Содержание файла:», final_str); \\ Выводим содержимое файла на консоль
fclose(f);
>
Основные функции для работы с файлами в языке Си
Есть ряд функций в языке Си, который позволяет манипулировать с файлами и потоками передачи данных. Основные из них были рассмотрены выше. Однако необходимо ознакомиться с их полным списком.
Открытие и закрытие файлового потока
Чтение из файлов
Запись в файл
Считывание русских символов из файла
setlocale(LC_ALL, «Russian») — вызов данной функции позволяет настроить поток на работу с кириллицей.
Отличие работы с потоками в Си от других языков
Как видно, язык Си не использует обращение к объектам для оперирования с файлами. Для открытия потока здесь даже не применяется конструкция new IOstream(). Ведь Cи является процедурным языком и в нем не используется парадигма ООП. Тем не менее, если открывать поток без сохранения в переменную, то дальнейшее применение функций должно сопровождаться записью в их параметры директории к файлу, какая была указана при открытии.
Ранее мы создавали переменную “f” для сохранения потока. Без нее всегда придется писать строку на подобие “C\:files\index.txt”. Данный подход достаточно неудобный и требует постоянной записи строки. При этом, все равно придется закрывать поток. Проще сохранить его в переменную – это дает гарантию тог, что работа всегда осуществляется с данным потоком.
Заключение
Работа с файлами является мощным инструментом каждого языка программирования. Ведь можно не только изменять содержание текстовых файлов, но и аудио, видео и и даже изображений через запись и чтение байтов. Так как в файлы записываются строки и символы, то перед записью их можно обрабатывать различными функциями или с помощью событий.
Большинство сложных приложений — аудиоконверторы, проигрыватели, графические редакторы и другие, работают с файлами. Важно уметь использовать возможности Си для работы с файловыми потоками, чтобы писать ложные автоматизированные сервисы.
Работу с файлами изучить достаточно просто. Ведь Си — это не объектно-ориентированный язык и обладает достаточно малым набором простых функций для обработки файлов. Режимы открытия файлов также не сложно запомнить. Ведь они практически идентичны. А благодаря наличию в языке встроенных функций по предоставлению информации об ошибках, можно гарантированно узнать, что файл так и не был создан, или в него ничего не было записано.
Работа с файлами
Для удобства обращения информация в запоминающих устройствах хранится в виде файлов.
Файл – именованная область внешней памяти, выделенная для хранения массива данных. Данные, содержащиеся в файлах, имеют самый разнообразный характер: программы на алгоритмическом или машинном языке; исходные данные для работы программ или результаты выполнения программ; произвольные тексты; графические изображения и т. п.
Файловой системой называется функциональная часть операционной системы, обеспечивающая выполнение операций над файлами. Примерами файловых систем являются FAT (FAT – File Allocation Table, таблица размещения файлов), NTFS, UDF (используется на компакт-дисках).
Существуют три основные версии FAT: FAT12, FAT16 и FAT32. Они отличаются разрядностью записей в дисковой структуре, т.е. количеством бит, отведённых для хранения номера кластера. FAT12 применяется в основном для дискет (до 4 кбайт), FAT16 – для дисков малого объёма, FAT32 – для FLASH-накопителей большой емкости (до 32 Гбайт).
Рассмотрим структуру файловой системы на примере FAT32.
Файловая структура FAT32
Устройства внешней памяти в системе FAT32 имеют не байтовую, а блочную адресацию. Запись информации в устройство внешней памяти осуществляется блоками или секторами.
Сектор – минимальная адресуемая единица хранения информации на внешних запоминающих устройствах. Как правило, размер сектора фиксирован и составляет 512 байт. Для увеличения адресного пространства устройств внешней памяти сектора объединяют в группы, называемые кластерами.
Кластер – объединение нескольких секторов, которое может рассматриваться как самостоятельная единица, обладающая определёнными свойствами. Основным свойством кластера является его размер, измеряемый в количестве секторов или количестве байт.
Файловая система FAT32 имеет следующую структуру.
Нумерация кластеров, используемых для записи файлов, ведется с 2. Как правило, кластер №2 используется корневым каталогом, а начиная с кластера №3 хранится массив данных. Сектора, используемые для хранения информации, представленной выше корневого каталога, в кластеры не объединяются.
Минимальный размер файла, занимаемый на диске, соответствует 1 кластеру.
Загрузочный сектор начинается следующей информацией:
Кроме того, загрузочный сектор содержит следующую важную информацию:
Сектор информации файловой системы содержит:
Таблица FAT содержит информацию о состоянии каждого кластера на диске. Младшие 2 байт таблицы FAT хранят F8 FF FF 0F FF FF FF FF (что соответствует состоянию кластеров 0 и 1, физически отсутствующих). Далее состояние каждого кластера содержит номер кластера, в котором продолжается текущий файл или следующую информацию:
Корневой каталог содержит набор 32-битных записей информации о каждом файле, содержащих следующую информацию:
Корневой каталог содержит набор 32-битных записей информации о каждом файле, содержащих следующую информацию:
В случае работы с длинными именами файлов (включая русские имена) кодировка имени файла производится в системе кодировки UTF-16. При этого для кодирования каждого символа отводится 2 байта. При этом имя файла записывается в виде следующей структуры:
Далее следует запись, включающая имя файла в формате 8.3 в обычном формате.
Работа с файлами в языке Си
Чтение символа из файла:
Запись символа в файл:
Функции fgets() и fputs() предназначены для ввода-вывода строк, они являются аналогами функций gets() и puts() для работы с файлами.
Результат выполнения — 2 файла
Работа с файлами в C++ описана здесь.
Видео
Программирование на Си урок 37: Работа с файлами в языке СиСкачать
Язык Си для начинающих / #9 - Работа с файламиСкачать
Как работать с текстовыми файлами в си (часть 1)Скачать
Язык Си с нуля - Урок 36 - Работа с файлом в текстовом режимеСкачать
Чтение из файла в Си (Кружок программирования)Скачать
Язык Си с нуля - Урок 37 - Работа с файлом в бинарном режимеСкачать