Где должен лежать файл для чтения c
Члены большинства типов в пространстве имен System.IO имеют параметр path , который позволяет указать абсолютный или относительный путь к ресурсу в файловой системе. Этот путь передается в API файловой системы Windows. В этом разделе рассматриваются форматы путей к файлам, которые можно использовать в операционных системах Windows.
Запись текста в файл
В рамках этого обзора мы рассмотрим простой сценарий: чтение и запись текста. Начнем с кода, который использует класс FileIO, чтобы записать текст в файл.
Сначала мы определим, где файл должен быть размещен. Windows.Storage.ApplicationData.Current.LocalFolder предоставляет доступ к локальной папке данных, которая создается для приложения во время установки. Дополнительные сведения о папках, доступных вашему приложению, см. в разделе Доступ к файловой системе.
Затем мы используем StorageFolder для создания файла (или его открытия, если он уже существует).
Класс FileIO предоставляет удобный способ записи текста в файл. FileIO.WriteTextAsync() заменяет все содержимое файла предоставленным текстом. FileIO.AppendLinesAsync() добавляет в файл коллекцию строк, записывая по одному строковому значению в каждую строку.
Что необходимо знать?
Ниже приведены основные типы, о которых нужно знать для чтения текста и записи текста в файл.
Windows.Storage.StorageFile представляет файл. Этот класс содержит свойства, которые предоставляют сведения о файле, и методы для создания, открытия, копирования, удаления и переименования файлов. Возможно, вы привыкли работать со строковыми путями. Есть ряд API среды выполнения Windows, принимающих строковый путь, но чаще всего вы будете использовать объект StorageFile для представления файла, так как некоторые файлы на платформе UWP могут быть без пути или путь к ним может быть слишком длинным. Используйте метод StorageFile.GetFileFromPathAsync() для преобразования строкового пути в объект StorageFile.
Класс FileIO предоставляет простой способ для чтения и записи текста. Этот класс также может читать и записывать массив байтов или содержимое буфера. Этот класс очень похож на класс PathIO. Основное различие заключается в том, что вместо использования строкового пути, как в PathIO, он принимает StorageFile.
Windows.Storage.StorageFolder представляет папку (каталог). Этот класс содержит методы для создания файлов, запроса содержимого папки, создания, переименования и удаление папок, а также свойства, которые предоставляют сведения о папке.
Вот распространенные способы получения StorageFolder.
-
позволяет пользователю перейти к требуемой папке. предоставляет объект StorageFolder для одной из локальных для приложения папок, например локальной, перемещаемой и временной папки. предоставляет StorageFolder для известных библиотек, таких как "Музыка" и "Изображения".
Работа с устаревшими устройствами
Если путь указывает на устаревшее устройство DOS, например CON , COM1 или LPT1 , он преобразуется в путь к устройству путем добавления перед ним последовательности \\.\ и возвращается в таком виде.
Путь, который начинается с имени устаревшего устройства, всегда интерпретируется как путь к устаревшему устройству с помощью метода Path.GetFullPath(String). Например, путь к устройству DOS CON.TXT будет выглядеть как \\.\CON , а путь к устройству DOS COM1.TXT\file1.txt будет выглядеть как \\.\COM1 .
Удаление знаков
Помимо удаленных ранее разделителей и относительных сегментов во время нормализации также удаляются некоторые дополнительные знаки:
Если сегмент заканчивается одной точкой, эта точка удаляется. (Сегмент одной или двойной точки нормализован на предыдущем шаге. Сегмент из трех или более периодов не нормализован и действительно является допустимым именем файла или каталога.)
Если путь не заканчивается разделителем, удаляются все конечные точки и пробелы (U+0020). Если последний сегмент содержит только одну или две точки, к нему применяется приведенное выше правило для относительных компонентов.
Это правило устанавливает, что вы можете создать имя каталога с конечным пробелом, добавив разделитель после пробела.
Создавать имена каталогов или файлов с конечным пробелом нельзя. Наличие конечных пробелов может затруднить или исключить возможность доступа к каталогу. В связи с этим при попытке обработать каталоги или файлы, имена которых содержат конечные пробелы, происходит сбой приложения.
Всё ещё ищете ответ? Посмотрите другие вопросы с метками c++ qt или задайте свой вопрос.
Похожие
Для подписки на ленту скопируйте и вставьте эту ссылку в вашу программу для чтения RSS.
Site design / logo © 2022 Stack Exchange Inc; user contributions licensed under cc by-sa. rev 2022.5.9.42071
Нажимая «Принять все файлы cookie» вы соглашаетесь, что Stack Exchange может хранить файлы cookie на вашем устройстве и раскрывать информацию в соответствии с нашей Политикой в отношении файлов cookie.
Для удобства обращения информация в запоминающих устройствах хранится в виде файлов.
Файл – именованная область внешней памяти, выделенная для хранения массива данных. Данные, содержащиеся в файлах, имеют самый разнообразный характер: программы на алгоритмическом или машинном языке; исходные данные для работы программ или результаты выполнения программ; произвольные тексты; графические изображения и т. п.
Каталог ( папка , директория ) – именованная совокупность байтов на носителе информации, содержащая название подкаталогов и файлов, используется в файловой системе для упрощения организации файлов.
Файловой системой называется функциональная часть операционной системы, обеспечивающая выполнение операций над файлами. Примерами файловых систем являются 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 кластеру.
Загрузочный сектор начинается следующей информацией:
- 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 в обычном формате.
Пропуск нормализации
Как правило, любой путь, передаваемый в API Windows передается в функцию GetFullPathName и нормализуется. Существует одно важное исключение: путь к устройству, который начинается со знака вопроса, а не с точки. Если путь не начинается с последовательности \\?\ (обратите внимание на использование канонической формы с обратной косой чертой), он нормализуется.
Зачем нужно пропускать нормализацию? Существует три основных причины:
Получение путей, которые в обычных обстоятельствах недоступны, но являются допустимыми. Например, невозможно каким-либо иным способом получить доступ к файлу или каталогу с именем hidden. .
Повышение производительности за счет пропуска нормализации в тех случаях, когда нормализация уже выполнена.
Пропуск нормализации и проверки максимальной длины пути является единственным отличием между двумя видами синтаксиса путей к устройствам. В остальных аспектах они идентичны. Пропуск нормализации следует использовать с осторожностью, поскольку в этом случае легко получить пути, при работе с которыми в обычных приложениях будут возникать трудности.
Пути, начинающиеся с последовательности \\?\ , по-прежнему нормализуются, если явно передать их в функцию GetFullPathName.
Вы можете передавать пути длиной более MAX_PATH символов в функцию GetFullPathName без \\?\ . Она поддерживает пути произвольной длины, которая ограничивается лишь максимальным размером строки, поддерживаемым в Windows.
Чтение текста из файла
Как и при записи в файл, чтение файла начинается с указания его расположения. Мы будем использовать то же расположение, что и в примере выше. Затем мы используем класс FileIO для чтения содержимого файла.
Вы можете также считывать каждую строку файла в отдельные строки в коллекции с помощью IList contents = await Windows.Storage.FileIO.ReadLinesAsync(sampleFile); .
Пример. Способы задать ссылку на один и тот же файл
В следующем примере демонстрируются некоторые способы задать ссылку на файл с использованием API в пространстве имен System.IO. В этом примере создается экземпляр объекта FileInfo и используются его свойства Name и Length, чтобы отобразить имя и длину файла.
Нормализация путей
Практически все передаваемые в API Windows пути нормализуются. При нормализации в Windows выполняются следующие действия:
- Идентифицируется путь.
- Текущий каталог применяется к неполным (относительным) путям.
- Выполняется канонизация разделителей каталогов.
- Вычисляются относительные компоненты каталога ( . для текущего и .. для родительского каталога).
- Удаляются некоторые символы.
Нормализация происходит неявно, но ее можно выполнить явным образом, вызвав Path.GetFullPath метод, который создает оболочку для вызова функции жетфуллпаснаме (). Также можно вызвать функцию GetFullPathName() Windows напрямую с помощью P/Invoke.
Идентификация пути
На первом шаге процесса нормализации осуществляется идентификация типа пути. Пути могут относиться к одной из нескольких категорий:
- Пути к устройствам: начинаются с двух разделителей и знака вопроса или точки ( \\? или \\. ).
- UNC-пути: начинаются с двух разделителей без знака вопроса или точки.
- Полные пути DOS: начинаются с буквы диска, разделителя томов и компонентов ( C:\ ).
- Пути к устаревшим устройствам ( CON , LPT1 ).
- Пути относительно корня текущего диска: начинаются с одного разделителя компонентов ( \ ).
- Пути относительно текущего каталога указанного диска: начинаются с буквы диска и разделителя томов, но не содержат разделителя компонентов ( C: ).
- Пути относительно текущего каталога: начинаются с любых других символов ( temp\testfile.txt ).
Тип пути определяет, будет ли каким-либо образом применяться текущий каталог. Кроме того, от типа пути зависит применяемый корень.
Применение текущего каталога
Если путь не является полным, система Windows применяет к нему текущий каталог. К UNC-путям и путям к устройствам текущий каталог не применяется. Также текущий каталог не применяется к полным путям к диску с разделителем C:\ .
Если путь начинается с одного разделителя компонентов, применяется диск текущего каталога. Например, для пути к файлу \utilities и текущего каталога C:\temp\ в результате нормализации будет получен путь C:\utilities .
Если путь начинается с буквы диска, разделителя томов и не содержит разделителя компонентов, применяется последний текущий каталог, установленный из командной оболочки. Если последний текущий каталог не был установлен, применяется диск сам по себе. Например, для пути D:sources , текущего каталога C:\Documents\ и последнего текущего каталога D:\sources\ на диске D: в результате будет получен путь D:\sources\sources . Пути, задаваемые относительно диска, являются распространенными источниками ошибок программ и логики скрипта. Предположение, что путь, начинающийся с буквы и двоеточия, не является относительным, очевидно неверно.
Если путь не начинается с разделителя, применяются текущий диск и текущий каталог. Например, для пути к файлу filecompare и текущего каталога C:\utilities\ в результате будет получен путь C:\utilities\filecompare\ .
Пути к устройствам DOS
В операционной системе Windows используется унифицированная объектная модель, которая указывает на все ресурсы, включая файлы. Эти пути к объектам доступны из окна консоли и предоставляются на уровень Win32 с использованием специальной папки с символьными ссылками, с которыми сопоставляются устаревшие пути DOS и UNC. Доступ к этой специальной папке осуществляется с использованием синтаксиса пути к устройству DOS, который может иметь одну из приведенных ниже форм:
Помимо использования буквы диска, вы можете указать том с помощью его GUID. Синтаксис будет иметь вид:
Путь к устройству DOS состоит из следующих компонентов:
Описатель пути к устройству ( \\.\ или \\?\ ), который идентифицирует путь как путь к устройству DOS.
Символьная ссылка на "реальный" объект устройства (C: в случае имени диска или Volume в случае GUID тома).
Первый сегмент пути к устройству DOS после описателя пути к устройству идентифицирует том или диск. (Например, \\?\C:\ и \\.\BootPartition\ .)
Для UNC-путей существует специальная ссылка, которая называется UNC . Пример:
Для UNC-путей к устройствам часть сервера или общего сетевого ресурса образует том. Например, в пути \\?\server1\e:\utilities\\filecomparer\ часть server1\utilities представляет сервер или общий сетевой ресурс. Это важно при вызове такого метода, как Path.GetFullPath(String, String) с сегментами с относительным путем к каталогу, поскольку переход дальше тома невозможен.
Пути к устройствам DOS являются полными по определению и не могут начинаться с относительным сегментом каталога ( . или .. ). Они никогда не задаются относительно текущего каталога.
Доступ к файловой системе
На платформе UWP доступ к папке ограничивается, чтобы обеспечить целостность и конфиденциальность данных пользователя.
Работа с файлами в языке Си
Для программиста открытый файл представляется как последовательность считываемых или записываемых данных. При открытии файла с ним связывается поток ввода-вывода . Выводимая информация записывается в поток, вводимая информация считывается из потока.
Когда поток открывается для ввода-вывода, он связывается со стандартной структурой типа FILE , которая определена в stdio.h . Структура FILE содержит необходимую информацию о файле.
Открытие файла осуществляется с помощью функции fopen() , которая возвращает указатель на структуру типа FILE , который можно использовать для последующих операций с файлом.
name – имя открываемого файла (включая путь),
type — указатель на строку символов, определяющих способ доступа к файлу:
- "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’ . Функция возвращает адрес строки.
Копирует строку в поток с текущей позиции. Завершающий нуль- символ не копируется.
Пример Ввести число и сохранить его в файле s1.txt. Считать число из файла s1.txt, увеличить его на 3 и сохранить в файле s2.txt.
Результат выполнения — 2 файла
Работа с файлами в C++ описана здесь.
Добрый день. Подскажите пожалуйста, возможно ли в С++ читать содержимое только файлов имеющих в своём имени только цифры? Например читать: 56.txt, 78.txt,99.txt и т.д. И не читать hellou.txt. Если да какие библиотеки и функции нужно использовать? В интернете по обработке имен файлов мало инфы.
Возможно сделать проверку имени файла на соответствие формату. Но само имя файла задаётся пользователем.
Здравствуйте, я сделал посимвольный вывод текстового файла. Как можно реализовать запрет переноса слов в консоли?
Считать количество выведенных символов в строке и длину следующего слова. Если количество символов +длина слова больше 80, то нужно перенести строчку и начать вывод с новой строки. При этом пост вольный вывод не получится - придется использовать буфер (массив) для хранения следующего слова.
Работа с файлами с использованием конструкций языка Си была рассмотрена здесь.
Для программиста открытый файл представляется как последовательность считываемых или записываемых данных. При открытии файла с ним связывается поток ввода-вывода . Выводимая информация записывается в поток, вводимая информация считывается из потока.
Для работы с файлами необходимо подключить заголовочный файл . В нем определены несколько классов и подключены заголовочные файлы
Файловый ввод-вывод аналогичен стандартному вводу-выводу, единственное отличие – это то, что ввод-вывод выполнятся не на экран, а в файл.
Если ввод-вывод на стандартные устройства выполняется с помощью объектов cin и cout , то для организации файлового ввода-вывода достаточно создать собственные объекты, которые можно использовать аналогично этим операторам.
При работе с файлом можно выделить следующие этапы:
- создать объект класса fstream (возможно, ofstream или ifstream );
- связать объект класса fstream с файлом, который будет использоваться для операций ввода-вывода;
- осуществить операции ввода-вывода в файл;
- закрыть файл.
В результате будет создан файл
Режимы открытия файлов устанавливают характер использования файлов. Для установки режима в классе ios предусмотрены константы, которые определяют режим открытия файлов.
Константа | Описание |
ios::in | открыть файл для чтения |
ios::out | открыть файл для записи |
ios::ate | при открытии переместить указатель в конец файла |
ios::app | открыть файл для записи в конец файла |
ios::trunc | удалить содержимое файла, если он существует |
ios::binary | открытие файла в двоичном режиме |
Режимы открытия файлов можно устанавливать непосредственно при создании объекта или при вызове метода open() .
Режимы открытия файлов можно комбинировать с помощью поразрядной логической операции ИЛИ | , например:
ios::out | ios::in - открытие файла для записи и чтения.
Канонизация разделителей
Все символы косой черты ( / ) преобразуются в стандартные разделители Windows, то есть символы обратной косой черты ( \ ). Если они присутствуют, последовательность символов косой черты после первых двух таких символов свертывается в один символ косой черты.
Регистр символов и файловая система Windows
Особенность файловой системы Windows заключается в том, что пользователи и разработчики, имеющие дело с другими операционными системами, могут сталкиваться с проблемами из-за того, что в именах каталогов и путях не учитывается регистр символов. Это значит, что в именах каталогов и файлов сохраняется регистр строк, используемый в момент их создания. Например, вызов метода
создает каталог с именем TeStDiReCtOrY. Если переименовать каталог или файл так, чтобы изменился регистр символов, в имени будет отражен регистр, используемый в момент переименования. Например, следующий код переименовывает файл test.txt в Test.txt:
Тем не менее при сравнении имен каталогов и файлов регистр символов не учитывается. Если выполнить поиск файла с именем "test.txt", API файловой системы .NET будут игнорировать регистр символов при сравнении. Таким образом, при поиске файла "test.txt" будут возвращены совпадения для файлов "Test.txt", "TEST.TXT", "test.TXT", а также любых других их вариантов с различным сочетанием букв в верхнем и нижнем регистре.
Как мне в программе задать относительный путь? Чтобы при переносе на другой компьютер, программа продолжала выполняться. Если прописываю полностью, все работает.
В файлы ресурсы запихнуть не могу (общий вес звука ~150мб).
@gil9red Это на стадии разработки, а потом будет иерархия такая: game.exe image sounds т.е. будут лежать рядо и exe и директории
Вы можете указывать относительный путь от бинарника, откуда его запускаете. Текущий путь бинарника можно узнать так
Решение проблемы различия относительных путей в случае отладки приложения и распространяемой версии, может решаться оп разному. Например: define для отладочной версии; установка output directorry, не в ..\debug, а в папку с рабочими файлами; Специальный ключ в реестре (QSettings), который указывает путь к папке; .
Относительный путь от бинарника должен быть
"Относительный путь от бинарника должен быть"
"Относительный путь отсчитывается не от .exe, а с уровня выше (это папка с make-файлами, которая задается при создании проекта у компилятора, что-то типа build-TestWidjets-Desktop_Qt_5_9_1_MinGW_32bit-debug)"
При создании проекта без Qт (без QFile) в релизе (папка "build-. -release") - относительный путь от бинарника, а не уровня выше, а вот в самом проекте Qt - на папку выше. При этом файл должен быть и в самом проекте, и в релизе. Либо бинарник просто копировать из релиза в проект, тогда он путь увидит, иначе в исходнике нужно будет переписывать путь под бинарник.
Пожалуйста, укажите прямо в ответе, чем ваше решение лучше или отличается от предложенных в ранее данных ответах.
Относительный путь отсчитывается не от .exe, а с уровня выше (это папка с make-файлами, которая задается при создании проекта у компилятора, что-то типа build-TestWidjets-Desktop_Qt_5_9_1_MinGW_32bit-debug)
Произвольный доступ к файлу
Система ввода-вывода С++ позволяет осуществлять произвольный доступ с использованием методов seekg() и seekp() .
Смещение определяет область значений в пределах файла ( long int ).
Система ввода-вывода С++ обрабатывает два указателя, ассоциированные с каждым файлом:
- get pointer g - определяет, где именно в файле будет производиться следующая операция ввода;
- put pointer p - определяет, где именно в файле будет производиться следующая операция вывода.
Позиция смещения определяется как
Позиция | Значение |
ios::beg | Начало файла |
ios::cur | Текущее положение |
ios::end | Конец файла |
Всякий раз, когда осуществляются операции ввода или вывода, соответствующий указатель автоматически перемещается.
С помощью методов seekg() и seekp() можно получить доступ к файлу в произвольном месте.
Можно определить текущую позицию файлового указателя, используя следующие функции:
- streampos tellg() - позиция для ввода
- streampos tellp() - позиция для вывода
В результате выполнения первой части программы будет создан файл
Вторая часть программы выведет в консоль
Ещё один пример. Допустим, нам нужно заполнять таблицу
Причем каждая вновь введенная строка должна размещаться в таблице непосредственно под "шапкой".
Алгоритм решения задачи следующий:
- формируем очередную строку для вывода
- открываем файл для чтения, считываем из него данные и сохраняем их в массив строк
- закрываем файл
- открываем файл для записи
- выводим "шапку" таблицы
- выводим новую строку
- выводим все сохраненные строки обратно в файл, начиная со строки после шапки
fstream inOut;
inOut.open( "file.txt" , ios::in); // открываем файл для ввода
// Считываем из файла имеющиеся данные
int count = 0;
while (inOut.getline(line[count], 100)) count++;
inOut.close(); // закрываем файл
Результат выполнения:
Полученный файл данных:
Здравствуйте Елена. Скажите, а можно ли как то узнать наступивший конец файла. Например, если количество строк в файле неизвестно, а нужно организовать цикл по их считыванию и прервать его по окончанию файла.
ifstream test( "U:\\prog struct17\\list.txt" ); // полное имя файла
if (!test) cout return 0;
while (!test.eof())< //пока не конец.
. >
Елена, здравствуйте! Помогите, пожалуйста. Есть код, работающий, но вывод делает в консоль, а так как вывод очень большой, то все результаты там не помещаются, только малая последняя часть. Подскажите, пожалуйста, где и что изменить, чтоб вывод записывало в файл. Если можно очень подробно или прям конкретным примером, я со всем этим только только столкнулась, поэтому пока не особо соображаю(( Вот мой код
import static java.lang.System.out;
import java.util.Arrays;
class Combinations
private static final int M = 12;
private static final int N = 24;
private static int [] generateCombinations( int [] arr)
if (arr == null)
arr = new int [M];
for ( int i = 0; i < M; i++)
arr[i] = i + 1;
return arr;
>
for ( int i = M - 1; i >= 0; i--)
if (arr[i] < N - M + i + 1)
arr[i]++;
for ( int j = i; j < M - 1; j++)
arr[j + 1] = arr[j] + 1;
return arr;
>
return null;
>
public static void main(String args[])
int [] arr = null;
while ((arr = generateCombinations(arr)) != null)
out.println(Arrays.toString(arr));
>
>
Думаю, что "в правильную". Можно попробовать взять, например, среднее арифметическое для каждой точки из двух файлов. Но это нужно анализировать при отладке.
Елена, здравствуйте. Подскажите, пожалуйста, как можно сделать так, чтобы из первой строки файла считывался размер массива, а из второй - его элементы, количество которых равно значению из первой строки. Не нашла у вас на сайте ничего про построчный ввод из файла. Заранее спасибо.
Ввод из файла осуществляется аналогично консольному вводу. После считывания порции данных указатель позиции файла автоматически перемещается на ее конец.
Да, но у вас в статьях нет ничего про, к примеру, getline. По вашим статьям я изучаю практически все, очень понятно и доходчиво написано, но этот блок то ли я не могу найти, то ли его нет. Подскажите, у вас на сайте есть статья, где более подробно описывается файловый ввод и вывод?
Здравствуйте, попыталась сделать вывод данных в файл, но почему то только создался документ, а данных там нет. Что не так?
ofstream fout( "file.txt" , ios::out);
fout.open( "file.txt" , ios::out);
for ( int i = 0; i < SIZE; i++)
for ( int j = 0; j < SIZE; j++)
printf( "%5d " , a[i][j]);
printf( "\n" );
Можно ли как-то скопировать половину строки ? Выше вы копировали от середины и до конца, но мне нужно наоборот- от начала до середины ( или 10-го символа)
Не совсем правильно сформулировала , от определённого индекса до определённого индекса. То есть, у нас есть строка(char sr[50]="blablablabla";) Я хочу скопировать с третього индекса по 10.
int main( int argc, char * argv[]) system( "chcp 1251" );
system( "cls" );
char line[LINES][150];
char str[30];
char s[] = "| | | | " ;
cout cin.getline(str, 30);
for ( int i = 0; str[i] != '\0'; i++)
s[i + 0] = str[i];
cout cin.getline(str, 30);
for ( int i = 0; str[i] != '\0'; i++)
s[i + 33] = str[i];
cout cin.getline(str, 30);
for ( int i = 0; str[i] != '\0'; i++)
s[i + 61] = str[i];
cout cin.getline(str, 30);
for ( int i = 0; str[i] != '\0'; i++)
s[i + 97] = str[i];
Почему файл объявлен как поток вывода, а открывается для ввода? Чему равен count? Где тут люди? Почему при вводе нет цикла?
Здравствуйте, подскажите как считать данные из файла, сохранённых в следующем виде: Check Type | Check name | Cost check | 12 |Full |50000 | 38 |Half |25000 | 156 |Special |79000 | и записать данные в структуру. Например: Поле "Struct->CheckType" имеет значение "12" Поле "Struct->CheckName" имеет значение "Full" Поле "Struct->CostCheck" имеет значение "50000"
Считывать по строкам, далее строку разделять по символу | и присваивать значения полям структуры. Если поля структуры целочисленные, то предусмотреть ещё перевод из строки в число.
Здравствуйте. Возникла проблема, когда пытался переделать ваш код под себя. Выдается очень странный баг, хотя программа компилируется. Я добавил возможность использования программы повторно, без перезапуска консоли, через цикл while. И немного изменил шапку и ее ввод. В общем вот код. Если получится найти причину, буду очень благодарен.
fstream abonent;
abonent.open( "file.txt" , ios::in);
int count = 0;
while (abonent.getline(line[count], 100)) count++;
abonent.close();
Пока вижу 2 бага, не знаю, какой Вы имеете в виду. 1. Когда вводим данные второго и последующих лиц, программа "глотает" Имя. 2. Если, допустим, фамилия второго человека окажется короче, чем у первого, то она будет дополнена "остатком" предыдущей фамилии.
Считать всю строку. Найти ее длину с помощью strlen() и сместить курсор на "минус" половину этого значения от текущей позиции.
Спасибо за статью. Познавательно. Пробую использовать данный вывод в файл, но возникла проблема: Файл создается и очищается (проверено) но запись в файл не происходит, и после выполнения данного кода
std::string textoutbuf = "yjjfhjshdsjhf dkcfjdhj jfcjh 111111" ;
textoutbuf.push_back('\n');
//m_sock.fileLog m_sock.fileLog INT qqq = GetLastError();
m_sock.fileLog.flush(); //очистить поток
m_sock.fileLog.close();
файл всегда нулевой длины. Что уже не пробовал, читал форумы но ответа пока не нашел. Может Вы подскажете в чем может быть проблема? Спасибо.
Возможно, я чего-то не учитываю, поскольку приведен только фрагмент кода. Но такая реализация позволит получить файл с данными:
А как записать данные в файл с названием, определяемым самим пользователем? Насколько я понял, в качестве названия файла можно использовать только константу (?)
извините, я наверно вас уже заколебал, с этой 4 строчкой. Но мне надо прочитать строчку из файла и вывести ее в консоль. Т.е. В файле есть 4 строка мне ее надо прочитать и вывести на экран. inOut.open( "file.txt" ,ios::out); for ( int i=0; i <4; i++) cout<
А как происходит перебор строк? Я как понимаю, мы читаем строку в массив line[1]; Потом читаем еще раз строку, но в массив line[2]; и т.д. до line[100]. А где мы говорим, что мы не читаем одну и туже строчку то? Как встать то на строчку 5? И прочитать что в строке 5 У нас Петров Петр.
Почему если в файле "file.txt" есть информация, то данный код не просто читает он удаляет все из файла?
При считывании строки указатель позиции в файле автоматически смещается на её длину. Поэтому если мы считаем 4 строки, то окажемся на начале 5-ой. Считав её, мы получим нужную нам информацию.
Если данные из файла считываются, то они не удаляются. Удаление данных происходит только при открытии файла в режиме записи (строка 32 последнего примера в статье).
Спасибо большое за ответы. Но а как мне получить строку под номером 4? Допустим я не знаю что в файле, и я хочу прочитать только 4 строчку. line[4] выводит все четвертые буквы всех строк, но не всю строку целиком. Может как то можно получить массив строк и массив символов за раз? Например my_line_txt[4][5] - четвертая строка 5 символ.
line[4] - это и есть 4-ая строка. Первый индекс в массиве line[][] - это номер строки, второй - номер символа в строке.
Подскажите пожалуйста (нигде найти не могу) Как выводить в файл строки сверху. было То, как зверь, она завоет, То заплачет, как дитя, Надо вставить сверху строчки, что бы получилось так: Буря мглою небо кроет, Вихри снежные крутя; То, как зверь, она завоет, То заплачет, как дитя, Только не говорите что для этого отдельный файл создавать надо. )
Если использовать флаг ios::beg Да, он ставит курсор в начало файла. Но он удалит весь текст который там был. И вставить строчку не получиться. Вместо вставки происходит замена.
Я, конечно, не буду говорить, что нужно создавать отдельный файл :) Но придётся считать всю информацию из файла и где-то её сохранить. Потом открыть файл для записи. Записать недостающие строки сверху, а потом снова выгрузить сохраненное содержимое файла.
А если надо заполнить такую таблицу что бы последние введенные данные были наверху. То есть, есть шапка которую нельзя трогать. файл 1 "с шапкой" файл 2 "с новой строкой" файл 3 = файл 1+файл2; // итоговый наш файл файл 2 = получили новую строку файл 4 = скопировать все с 4 строчки и ниже из файла №3 файл 3 = встаем на четвертую строчку и добавляем файл №2 с нашей строкой файл 3 = копируем все из файла 4. Только так можно это реализовать? Как можно установить курсор на 4 строчку? ----------------------------------------------------------------------------------- | Фамилия | Имя | Отчество | дата рождения | хобби | ----------------------------------------------------------------------------------- |_________|_____|__________|_______________|________| |_________|_____|__________|_______________|________| |_________|_____|__________|_______________|________| |_________|_____|__________|_______________|________|
Как можно установить курсор на 4 строчку? И как можно скопировать все что ниже 4 строчки. Или удалить все что выше 4 строчки.
В этом разделе описывается,как приступить к чтению файлов и записи в файлы в приложении универсальной платформы Windows (UWP). Здесь представлены основные интерфейсы API и типы, а также ссылки на дополнительные ресурсы.
Это не руководство. Если вам необходимо полное руководство, ознакомьтесь с разделом Создание, запись и чтение файла, в котором показано, как создать, считать и записать файл, а также использовать буферы и потоки. Вас также может заинтересовать пример доступа к файлам, в котором показано, как создать, считать, записать, скопировать и удалить файл, а также как получать свойства файла и запоминать файлу или папку, чтобы ваше приложение легко могло получить доступ к ним снова.
Мы рассмотрим код для записи текста в файл и чтения текста из файла, а также для получения доступа к локальным, перемещаемым и временным папкам приложения.
Полезные интерфейсы API и документы
Ниже приведено краткое описание интерфейсов API и другая полезная документация, которая поможет вам приступить к работе с файлами и папками.
Вычисление относительных компонентов
При обработке пути выполняется вычисление любых его компонентов или сегментов, которые состоят из одной или двух точек ( . или .. ):
Если обнаруживается одна точка, текущий сегмент удаляется, поскольку он ссылается на текущий каталог.
Если обнаруживаются две точки, удаляются текущий и родительский сегмент, поскольку в этом случае задается ссылка на родительский каталог.
Родительские каталоги удаляются только в том случае, если они не находятся после корня пути. Корень пути зависит от его типа. Это будет диск ( C:\ ) для путей DOS, сервер или общий сетевой ресурс для UNC-путей ( \\Server\Share ) и префикс пути к устройству для путей к устройствам ( \\?\ или \\.\ ).
UNC-пути
UNC-пути (универсальное соглашение об именовании) используются для доступа к сетевым ресурсам и имеют следующий формат:
- Имя сервера или узла, которому предшествуют символы \\ . В качестве имени сервера может выступать имя компьютера NetBIOS, а также IP-адрес или полное доменное имя (поддерживаются адреса IPv4 и IPv6).
- Имя общего ресурса, которое отделяется от имени узла символами \ . Имя сервера и имя общего ресурса в совокупности образуют том.
- Имя каталога. Символ разделителя каталогов служит для разделения подкаталогов во внутренней иерархии каталога.
- Необязательное имя файла. Символ разделителя каталогов служит для разделения пути к файлу и его имени.
Ниже приводятся некоторые примеры UNC-путей:
Path | Описание |
---|---|
\\system07\C$\ | Корневой каталог диска C: на компьютере system07 . |
\\Server2\Share\Test\Foo.txt | Файл Foo.txt в тестовом каталоге тома \\Server2\Share . |
UNC-пути всегда должны быть полными. Они могут включать сегменты с относительным путем к каталогу ( . и .. ), однако они должны быть частью полного пути. Использовать относительные пути можно только посредством сопоставления UNC-пути с буквой диска.
Традиционные пути DOS
Стандартный путь DOS может состоять из трех компонентов:
- Буква тома или диска, после которой следует разделитель томов ( : ).
- Имя каталога. Символ разделителя каталогов служит для разделения подкаталогов во внутренней иерархии каталога.
- Необязательное имя файла. Символ разделителя каталогов служит для разделения пути к файлу и его имени.
Если присутствуют все три компонента, путь является абсолютным. Если буква тома или диска не указана и имя каталога начинается с символа разделителя каталогов, такой путь задан относительно корня текущего диска. В противном случае путь задан относительно текущего каталога. В следующей таблице показаны некоторые возможные пути к каталогам и файлам.
Путь | Описание: |
---|---|
C:\Documents\Newsletters\Summer2018.pdf | Абсолютный путь к файлу из корня диска C: . |
\Program Files\Custom Utilities\StringFinder.exe | Абсолютный путь из корня текущего диска. |
2018\January.xlsx | Относительный путь к файлу в подкаталоге текущего каталога. |
..\Publications\TravelBrochure.pdf | Относительный путь к файлу в каталоге, начиная с текущего каталога. |
C:\Projects\apilibrary\apilibrary.sln | Абсолютный путь к файлу из корня диска C: . |
C:Projects\apilibrary\apilibrary.sln | Относительный путь из текущего каталога диска C: . |
Обратите внимание на различия между двумя последними путями. В обоих случаях задается необязательный описатель тома ( C: ), однако первый путь, в отличие от второго, начинается с корня указанного тома. В результате первый путь является абсолютным из корневого каталога диска C: , тогда как второй — относительным из текущего каталога C: . Использование второй формы пути в тех случаях, когда предполагается наличие первой, является распространенным источником ошибок, связанных с путями к файлам в Windows.
Чтобы определить, является ли путь к файлу полным (такой путь не зависит от текущего каталога и не изменяется при смене текущего каталога), можно вызвать метод Path.IsPathFullyQualified. Обратите внимание, что такой путь может включать сегменты с относительным путем к каталогу ( . и .. ), но при этом по-прежнему будет полным, если разрешенный путь всегда указывает на одно и то же место.
В приведенном ниже примере показано различие между абсолютными и относительными путями. Предполагается, что каталог D:\FY2018\ существует и вы не установили какой-либо текущий каталог для диска D:\ из командной строки перед запуском этого примера.
Если вы хотите увидеть комментарии к коду, переведенные на языки, отличные от английского, сообщите нам на странице обсуждения этой проблемы на сайте GitHub.
Папки приложения
При установке приложение UWP в каталоге c:\users\AppData\Local\Packages\ создается несколько папок для хранения, помимо прочего, локальных, перемещаемых и временных файлов приложения. Приложению не нужно объявлять какие-либо возможности для доступа к этим папкам, и они недоступны другим приложениям. Эти папки также удаляются при удалении приложения.
Вот некоторые из папок приложения, которые часто используются.
LocalState: для локальных на текущем устройстве данных. При резервном копировании устройства данные в этом каталоге сохраняются в образе резервной копии в службе OneDrive. Если пользователь сбрасывает или заменяет устройство, эти данные будут восстановлены. Для доступа к этой папке используйте Windows.Storage.ApplicationData.Current.LocalFolder. . Сохраните локальные данные, которые не требуется архивировать в OneDrive, в объекте Windows.Storage.ApplicationData.Current.LocalFolder. , к которому можно обратиться с помощью Windows.Storage.ApplicationData.Current.LocalCacheFolder .
RoamingState: для данных, которые должны реплицироваться на всех устройствах, где установлено приложение. Windows ограничивает объем данных, которые будут перемещаться, поэтому сохраняйте здесь только параметры пользователя и небольшие файлы. Для доступа к перемещаемой папке используйте Windows.Storage.ApplicationData.Current.RoamingFolder .
TempState: для данных, которые могут быть удалены, когда приложение не выполняется. Для доступа к этой папке используйте Windows.Storage.ApplicationData.Current.TemporaryFolder .
Доступ к остальной части файловой системы
Приложение UWP должно объявить свои намерения для доступа к определенной библиотеке пользователя, добавив соответствующую возможность в свой манифест. Затем при установке приложения пользователям предлагается подтвердить, что они разрешили доступ к указанной библиотеке. Если это не так, приложение не устанавливается. Существуют возможности для доступа к библиотекам изображений, видео и музыки. Полный список доступен в разделе Объявление возможностей приложения. Чтобы получить StorageFolder для этих библиотек, используйте класс Windows.Storage.KnownFolders.
Библиотека документов
Хотя и существует возможность доступа к библиотеке документов пользователя, она ограничена, то есть приложение, которое ее объявит, будет отклонено в Microsoft Store, если вы не выполните процедуру получения специального разрешения. Оно не предназначено для общего использования. Вместо этого используйте средства выбора файла или папки (см. разделы Открытие файлов и папок с помощью средства выбора и Сохранение файла с помощью средства выбора), позволяющие пользователям перейти к папке или файлу. При переходе пользователей к файлу или папке они неявно разрешают приложению доступ к ним, и система разрешает доступ.
Общий доступ
Кроме того, ваше приложение может объявить ограниченную возможность broadFileSystem в манифесте, которая также должна быть утверждена в Microsoft Store. Затем приложение сможет получить доступ к любому файлу, к которому обращается пользователь, без вмешательства средства выбора файла или папки.
Полный список расположений, которые доступны приложениям, приведен в разделе Разрешения на доступ к файлам.
Читайте также: