Как считать название файла c

Обновлено: 06.07.2024

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

В языке программирования C указатель на файл имеет тип FILE и его объявление выглядит так:

С другой стороны, функция fopen() открывает файл по указанному в качестве первого аргумента адресу в режиме чтения ("r"), записи ("w") или добавления ("a") и возвращает в программу указатель на него. Поэтому процесс открытия файла и подключения его к программе выглядит примерно так:

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

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

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

Объявление функции fopen() содержится в заголовочном файле stdio.h, поэтому требуется его подключение. Также в stdio.h объявлен тип-структура FILE.

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

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

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

fscanf()

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

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

Допустим, у нас есть файл содержащий такое описание объектов:

Тогда, чтобы считать эти данные, мы можем написать такую программу:

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

fgets()

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

Такой вызов функции прочитает из файла, связанного с указателем myfile, одну строку текста полностью, если ее длина меньше 50 символов с учетом символа '\n', который функция также сохранит в массиве. Последним (50-ым) элементом массива str будет символ '\0', добавленный fgets() . Если строка окажется длиннее, то функция прочитает 49 символов и в конце запишет '\0'. В таком случае '\n' в считанной строке содержаться не будет.

В этой программе в отличие от предыдущей данные считываются строка за строкой в массив arr. Когда считывается следующая строка, предыдущая теряется. Функция fgets() возвращает NULL в случае, если не может прочитать следующую строку.

getc() или fgetc()

Функция getc() или fgetc() (работает и то и другое) позволяет получить из файла очередной один символ.

Приведенный в качестве примера код выводит данные из файла на экран.

Запись в текстовый файл

Также как и ввод, вывод в файл может быть различным.

  • Форматированный вывод. Функция fprintf ( файловый_указатель, строка_формата, переменные ) .
  • Посточный вывод. Функция fputs ( строка, файловый_указатель ) .
  • Посимвольный вывод. Функция fputc() или putc( символ, файловый_указатель ) .

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

Запись в каждую строку файла полей одной структуры:

Построчный вывод в файл ( fputs() , в отличие от puts() сама не помещает в конце строки '\n'):

Пример посимвольного вывода:

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

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

При открытии файла для двоичного доступа, вторым параметром функции fopen() является строка "rb" или "wb".

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

Функции fread() и fwrite() принимают в качестве параметров:

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

Эти функции возвращают количество успешно прочитанных или записанных данных. Т.е. можно "заказать" считывание 50 элементов данных, а получить только 10. Ошибки при этом не возникнет.

Пример использования функций fread() и fwrite() :

Здесь осуществляется попытка чтения из первого файла 50-ти символов. В n сохраняется количество реально считанных символов. Значение n может быть равно 50 или меньше. Данные помещаются в строку. То же самое происходит со вторым файлом. Далее первая строка присоединяется ко второй, и данные сбрасываются в третий файл.

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

От в пхп это делается легко функция scandir() принимает путь к директории и на выходе возвращает массив с именами файлов всей директории, также лего проверить файл это или нет функцией file_exests() передаем имя если true, то файл не true, то скорее директория.

Как это все сделать в С++ под виндовс.

Записать в текстовый файл все имена файлов в директории
Написать дополнительный файл, подключаемый к. cpp, который записывает в текстовый файл все имена.

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


Вывести список всех файлов из указанной директории, имена которых содержат русские буквы
Помогите с заданием, заранее спасибо! Вывести список всех файлов из указанной директории, имена.

Как считать имена файлов из заданной директории и напечатать их?
Нижеприведенный код зависает: vFolder = 'E:ASPDictionary ' set fsObject =.

ПерС, Не работает, ошибка не удается открыть <dir.h> файла нету.

Добавлено через 5 часов 2 минуты
Ладно я так смотрю вы не поняли что нужно сделать. Есть директория, мне нужно считать ее содержимое, имена файлов и записать в текстовый файл. Как считать содержимое директории.

Добавлено через 19 минут
От нашол функцию, но ничего не ясно как она работает, похоже функция из винапи.

Вообще не понятно что это за переменные, ясно что возвращает объект типа WIN32_FIND_DATA, но как мне из этого объекта вытянуть содержимое директории? Метод похоже cFileName() возвращает имя самой директории ну я пробовал вывело имя директории. МСДН тяжело читать, там все на английском, да и еще без предворительной подготовки, мб на русском есть какой нить хороший МСДН??

Добавлено через 1 минуту
Мне вообще весь МСДН и нафиг не нужно, нужно только получить содержимое директории, наверно одну функцию понять как использовать, мб кто разьяснит?!

Добавлено через 3 минуты
Вообще этот объект ни понятно что описывает, в описании вроде написано что файл описывает, ну и структуру если посмотреть то выходит что файл, ну а как так? Я ж туда вроде путь к директории передал?

Добавлено через 6 минут
И почему у меня срабатывает антивирус, я от пытаюсь вывести содержимое объекта WIN32_FIND_DATA и у меня срабатывает антивируст? Вот код:

Срабатывает антивирус: Avast! Экран файловой системы блокировал угрозу. Дополнительные действия не требуются. Все зависит от ОСи. Вот, в ДОСе есть такая сладкая парочка findfist-findnext. Windows, кажись, тоже поддерживает.
У самой Винд-Апи тоже полно аналогичных штук, даже названия те же, но большими буквами. У Qt вообще все хорошо в классе QDir. Ну а если Ось другая и кросса не ищите - "пилите, Шура, они внутри - золотые"

Добавлено через 3 минуты
Наверное, не совсем то.

Срабатывает антивирус: Avast! Экран файловой системы блокировал угрозу. Я бы тоже на его месте заблокировал. Чего это в мою файловую систему лезешь? Это называется "параноидальный режим работы антивируса". Либо установи его в другой режим, либо выключи на время этой работы. katsidelin, Ну я твой пример чуток переделал, у меня просто строки string с ними не работает, пришлось на wstring поменять, отак:

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

Просветите новичка как правильно проект нужно было строить. Конечно сохранить строки wstring в файл, а затем считать в string мб тоже вариант, а если оно не правильно считает, я не пробовал, как вообще правильно нужно было делать.

Добавлено через 3 минуты
Я от помню что мне советовали в настройках поменять где то что то и тогда вроде как строки string станут wstring и проблем не будет, среда visual studio 2010.

Добавлено через 23 минуты
Ну от господа все таки подтвердилось, что бы получить из wstring string нужно просто записать в файл данные а уже оттуда их считать в string

Это способ перевода из wstring в string ну и наверно наоборот. Да можно функции две создать string_to_wstring() и wstring_to_string() которые будут переводить одни строки в другие используя временный файл. В принципе для моего проекта этот вариант годиться. Но мб есть какое нить более лучшее "правильное" решение, чо то меня смущает что оно все так запутано получается и мой код как всегда получается такой что другой человек в нем не разберется, я сам в нем с трудом разбираюсь на следующий день, там 700 строк кода и я уже смотрю его тяжело читать, а если не знающий человек будет смотреть, то он фиг в нем разберется, не разобраться он то разберется только придется затратить день - три дня на разбор, а мб для кого то и больше, короче гамно код получается на С++, я щас код пхп на С++ переписываю, так код на пхп я писал полтора года назад и то в нем быстро разобрался наверно потому что язык высокоуровневый, а от на С++ все плохо получается.

А ForEveR что то советовал, там как то проект настроить для строк, я так и не понял.

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

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

Перегрузки

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

Возвращает имя файла и расширение указанной строки пути.

GetFileName(ReadOnlySpan<Char>)

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

Параметры

Диапазон только для чтения, содержащий путь, из которого нужно получить имя и расширение файла.

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

Символы, следующие за последним символом разделителя каталогов в пути path .

Комментарии

Возвращаемый диапазон только для чтения содержит символы пути, следующие за последним разделителем в path . Если последним символом в path является символ или разделитель каталога, метод возвращает значение ReadOnlySpan<T>.Empty . Если path не содержит символа разделителя, метод возвращает значение path .

См. также раздел

Применяется к

GetFileName(String)

Возвращает имя файла и расширение указанной строки пути.

Параметры

Строка пути, из которой нужно получить имя файла и расширение.

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

Символы, следующие за последним символом разделителя каталогов в пути path . Если последним символом параметра path является символ разделения тома или каталога, этот метод возвращает Empty. Если значением параметра path является null , метод возвращает null .

Исключения

Примеры

в следующем примере демонстрируется поведение GetFileName метода на настольной платформе на основе Windows.

Комментарии

Возвращаемое значение —, null Если путь к файлу — null .

Символы разделения, используемые для определения начала имени файла, — это DirectorySeparatorChar и AltDirectorySeparatorChar .

поскольку \ является допустимым именем файла в unix, GetFileName работа с платформами на базе unix не может правильно возвращать имя файла из пути на основе Windows, например C: \ mydir \ myfile. ext, но GetFileName выполняемые на платформах на основе Windows могут правильно возвращать имя файла из пути на основе unix, например /тмп/мифиле.екст, поэтому поведение GetFileName метода не является строго одинаковым на платформах на базе unix и Windows.

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

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

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

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

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


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

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

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

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

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

Файловая система FAT32

Файловая система 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+" — открыть файл для чтения и дополнения, если файл не существует, то он создаётся.

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

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

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


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

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

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

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

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


Копирует строку в поток с текущей позиции. Завершающий нуль- символ не копируется.
Пример Ввести число и сохранить его в файле s1.txt. Считать число из файла s1.txt, увеличить его на 3 и сохранить в файле s2.txt.

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