Как очистить файл с fstream
Для работы с файлами в стандартной библиотеке определен заголовочный файл fstream , который определяет базовые типы для чтения и записи файлов. В частности, это:
- ifstream : для чтения с файла
- ofstream : для записи в файл
- fstream : совмещает запись и чтение
Для работы с данными типа wchar_t для этих потоков определены двойники:
- wifstream
- wofstream
- wfstream
Открытие файла
При операциях с файлом вначале необходимо открыть файл с помощью функции open() . Данная функция имеет две версии:
- open(путь)
- open(путь, режим)
Для открытия файла в функцию необходимо передать путь к файлу в виде строки. И также можно указать режим открытия. Список доступных режимов открытия файла:
- ios::in : файл открывается для ввода (чтения). Может быть установлен только для объекта ifstream или fstream
- ios::out : файл открывается для вывода (записи). При этом старые данные удаляются. Может быть установлен только для объекта ofstream или fstream
- ios::app : файл открывается для дозаписи. Старые данные не удаляются.
- ios::ate : после открытия файла перемещает указатель в конец файла
- ios::trunc : файл усекается при открытии. Может быть установлен, если также установлен режим out
- ios::binary : файл открывается в бинарном режиме
Если при открытии режим не указан, то по умолчанию для объектов ofstream применяется режим ios::out , а для объектов ifstream — режим ios::in . Для объектов fstream совмещаются режимы ios::out и ios::in .
std::ofstream out; // поток для записи out.open("hello1.txt"); // окрываем файл для записи std::ofstream out2; out2.open("hello2.txt", std::ios::app); // окрываем файл для дозаписи std::ofstream out3; out2.open("hello3.txt", std::ios::out | std::ios::trunc); // установка нескольких режимов std::ifstream in; // поток для чтения in.open("hello4.txt"); // окрываем файл для чтения std::fstream fs; // поток для чтения-записи fs.open("hello5.txt"); // окрываем файл для чтения-записи
Однако в принципе необязательно использовать функцию open для открытия файла. В качестве альтернативы можно также использовать конструктор объектов-потоков и передавать в них путь к файлу и режим открытия:
fstream(путь) fstream(путь, режим)
При вызове конструктора, в который передан путь к файлу, данный файл будет автоматически открываться:
std::ofstream out("hello.txt"); std::ifstream in("hello.txt"); std::fstream fs("hello.txt", std::ios::app);
В данном случае предполагается, что файл «hello.txt» располагается в той же папке, где и файл программы.
Вообще использование конструкторов для открытия потока является более предпочтительным, так как определение переменной, представляющей файловой поток, уже преполагает, что этот поток будет открыт для чтения или записи. А использование конструктора избавит от ситуации, когда мы забудем открыть поток, но при этом начнем его использовать.
В процессе работы мы можем проверить, окрыт ли файл с помощью функции is_open() . Если файл открыт, то она возвращает true:
std::ifstream in; // поток для чтения in.open(«hello.txt»); // окрываем файл для чтения // если файл открыт if (in.is_open())
Закрытие файла
После завершения работы с файлом его следует закрыть с помощью функции close() . Также стоит отметить, то при выходе объекта потока из области видимости, он удаляется, и у него автоматически вызывается функция close.
#include #include int main() < std::ofstream out; // поток для записи out.open("hello.txt"); // окрываем файл для записи out.close(); // закрываем файл std::ifstream in; // поток для чтения in.open("hello.txt"); // окрываем файл для чтения in.close(); // закрываем файл std::fstream fs; // поток для чтения-записи fs.open("hello.txt"); // окрываем файл для чтения-записи fs.close(); // закрываем файл >
Работа с текстовыми файлами с помощью файловых потоков
Для работы с файлами используются специальные типы данные, называемые потоками. Поток ifstream служит для работы с файлами в режиме чтения. Поток ofstream служит для работы с файлами в режиме записи. Для работы с файлами в режиме, как чтения, так и записи служит поток fstream.
В программах на C++ при работе с текстовыми файлами необходимо подключать библиотеки iostream и fstream.
Для того, чтобы записывать данные в текстовый файл необходимо:
1. Описать переменную типа ofstream
2. Отрыть файл с помощью функции open.
3. Вывести информацию в файл с помощью cout.
4. Обязательно закрыть файл.
Для того, чтобы считывать данные из текстового файл необходимо:
1. Описать переменную типа ifstream
2. Отрыть файл с помощью функции open.
3. Считать информацию из файла с помощью cin, при считывании каждой порции данных необходимо проверять, что чтение возможно.
Запись информации в текстовый файл
Для того, чтобы начать работать с текстовым файлом необходимо описать переменную типа ofstream. Например, с помощью оператора
будет создана переменная F для записи информации в файл.
На следующем этапе файл необходимо открыть для записи. В общем случае оператор открытия файла будет иметь вид:
F.open(«file», mode);
Здесь F – переменная, описанная как ofstream,
file – полное имя файла на диске, например, D:\\STUDENT\\abc.txt.
mode – режим работы с открываемым файлом:
· ios::in – открыть файл в режиме чтения данных, этот режим является
режимом по умолчанию для потоков ifstream;
· ios::out – открыть файл в режиме записи данных, этот режим является
режимом по умолчанию для потоков ofstream;
· ios::app – открыть файл в режиме записи данных в конец файла;
· ios::ate – передвинуться в конец уже открытого файла;
· ios::trunc – очистить файл, это же происходит в режиме ios::out;
· ios::nocreate – не выполнять операцию открытия файл, если он не
· ios::noreplace – не открывать существующий файл.
· ios::binary – открыть двоичный файл
Параметр mode может отсутствовать, в этом случае файл открывается в режиме по умолчанию для данного потока
ios::in – для потоков ifstream,
ios::out – для потоков ofstream.
После удачного открытия файла (в любом режиме) в переменной F будет храниться true, в противном случае false. Это позволит проверять корректность операции открытия файла.
Открыть файл в режиме записи можно одним из следующих способов:
F.open(«D:\\STUDENT\\abc.txt», ios::out);
//Второй способ, режим ios::out
// является режимом по умолчанию для потока ofstream.
F.open(«D:\\STUDENT\\abc.txt»);
//Третий способ объединяет
//описание переменной типа поток
//и открытие файла в одном операторе.
ofstream F(«D:\\STUDENT\\abc.txt», ios::out);
После открытия файла в режиме записи, будет создан пустой файл, в который можно будет записывать информацию. Если Вы хотите открыть существующий файл, то в качестве режима следует использовать значение ios::app.
После открытия файла в режиме записи, в него можно писать точно также, как и на экран, только вместо стандартного устройства вывода cout необходимо указать имя открытого для записи файла.
Например, для записи в поток F переменной a, оператор вывода будет иметь вид:
Для последовательного вывода в поток G переменных b, c и d оператор вывода станет таким:
В качестве примера рассмотрим следующую задачу.
ЗАДАЧА. Создать текстовый файл D:\abc.txt и записать туда n вещественных
using namespace std;
//Описывает поток для записи данных в файл.
//Открываем файл в режиме записи,
// режим ios::out устанавливается по умолчанию.
cout //Ввод очередного числа.
//Запись в файл очередного числа и символа табуляции.
Чтение информации из текстового файла
Для того чтобы прочитать информацию из текстового файла необходимо описать переменную типа ifstream. После этого необходимо открыть для чтения с помощью оператора open. Если переменную назвать F, то первые два оператора будут такими:
После открытия файла в режиме чтения, из него можно считывать информацию точно так же, как и клавиатуры, только вместо стандартного устройства ввода cin необходимо указать имя открытого для чтения файла.
Например, для ввода из потока F в переменную a, оператор ввода будет иметь вид:
Для последовательного ввода из потока G в переменные b, с и d оператор ввода станет таким:
Два числа в текстовом файле считаются разделенными, если между ними есть хотя бы один из символов: провел, табуляция, символ конца строки.
Хорошо если программисту заранее известно, сколько и каких значений хранится в текстовом файле. Однако часто просто известен тип значений, хранящихся в файле, при этом количество значений в файле может быть различным. При решении подобной проблемы необходимо считывать значения из файла по одному, а перед каждым считыванием проверять достигнут ли конец файла. Для проверки достигнут или нет конец файла, служит функция
Здесь F – имя потока, функция возвращает логическое значение: true – если достигнут конец файла, если не достигнут функция возвращает значение false.
Цикл для чтения содержимого всего файла можно записать так:
обработка значения переменной a
Рассмотрим следующую задачу.
ЗАДАЧА. В текстовом файле D:\abc.txt хранятся вещественные числа, вывести их на экран и вычислить их количество
using namespace std;
//Открываем файл в режиме чтения.
//Если открытие файла прошло корректно, то
//Цикл для чтения значений из файла, выполнение цикла
// прервется, когда достигнем конца файла, в этом случае
// f.eof() вернет истину.
//Чтение очередного значения из f в переменную a.
//Вывод значения переменной a на экран.
//Увеличение количества считанных чисел.
//Вывод на экран количества считанных чисел.
//Если открытие файла прошло некорректно, то вывод
// сообщение, об отсутствии такого файла.
Существует возможность открывать файл с данными таким образом, чтобы в него можно было дописывать информацию. Рассмотрим эту возможность на примере решения следующей задачи.
ЗАДАЧА. В файле D:\abc.txt (см. рис.) хранится массив вещественных чисел, дописать в файл этот же массив, упорядочив его по возрастанию.
Рис. Содержимое файла D:\abc.txt
using namespace std;
ifstream f;//Поток для чтения.
ofstream g;//Поток для записи.
//Открываем файл в режиме чтения.
//Если открытие файла прошло корректно, то
//цикл для чтения значений из файла, выполнение цикла
// прервется, когда достигнем конца файла, в этом
// случае f.eof() вернет истину.
//Чтение очередного значения из потока f в очередной
// элемент массива a.
//Вывод элемента массива a на экран.
//Увеличение количества считанных чисел.
//Вывод на экран количества считанных чисел.
cout //Упорядочение массива
//Закрываем поток для чтения.
//Открываем поток в режиме дозаписи.
//Запись в файл символа табуляции для разделения
//последнего символа исходного файла и
// первого элемента дозаписываемого в массив.
// Запись в файл элемента массива и символа табуляции.
//Если открытие файла прошло некорректно, то вывод
// сообщения об отсутствии такого файла.
При запуске программы на экране в консольном режиме появится окно, подобное представленному на рис.. В результате работы программы изменится содержимое файла D:\abc.txt (см. рис.).
Рис. Результаты работы программы задачи
Рис. Содержимое файла D :\ abc . txt после запуска программы
Но если повторно запустить программу уже над обновленным файлом D:\abc.txt, то на экране можно будет увидеть следующее (см. рис.) и в файл D:\abc.txt станет таким (см. рис.).
Дело в том, что при первом запуске программы в файл D:\abc.txt послепоследнего элемента массива был записан символ табуляции. Таким образом, в конце файла после последнего числа находится символ табуляции. При повторном чтении информации из файла происходит следующее: программа нормально считывает последнее число, записывает его в массив. Происходит возврат к началу цикла while, программа проверяет, достигнут ли конец файла. А так как после числа есть символ табуляции (это мог быть и символ пробел, перехода на новую строку или их комбинация), то конец файла не достигнут, происходит вход в цикл. После этого оставшиеся до конца файла символы считываются и интерпретируются, как вещественное число типа float. В результате этого получается дополнительное ненужное число. На рис. – это значение -4.31602E+008.
Рис. Результаты работы программы после повторного запуска
Рис. Содержимое файла D:\abc.txt после повторного запуска программы
В этом причина неправильной работы программы при повторном запуске. Причину нашли, но как исправить работу программы? В этом конкретном случае это не сложно, надо добиться того, чтобы программа не записывала в файл символ табуляции после последнего числа. Для этого изменим последний цикл for следующим образом.
После исправлений программа будет работать правильно (рис.).
Рис. Результат повторного запуска исправленной программы для решения задачи
Рис. Содержимое файла D:\abc.txt после повторного запуска исправленной программы
Внимание. Если в текстовом файле хранятся числовые значения, то после последнего числа не должно быть пробелов символов табуляции и конца строки.
Пусть есть файл D:\abc4.txt, в котором в первой строке хранится количество значений, а далее сами значения (см. рис.).
Рис. Содержимое файла D:\abc4.txt
using namespace std;
ifstream f;//Поток для чтения данных
//Считываем из файла в переменную
//n количество вещественных чисел
//Выделяем память для массива вещественных чисел
//В цикле последовательно считываем значения
f>>a[i]; //Считывание значение из файла в массив
//Вывод элемента массива на экран
Аналогично можно работать со структурами
Рассмотрим пример: программа считывает информацию из текстового файла о студентах (Фамилия, Средний балл, Стипендия) и заносит эту информацию в массив структур.
using namespace std;
ifstream f;//Поток для чтения данных
struct student a[10];
//Считываем из файла в переменную
// n количество записей
//Выделяем память для массива
//В цикле последовательно считываем значения
//Считывание значение из файла в массив
//Вывод элемента массива на экран
Задания (без вариантов)
Как очистить файл используя файловые потоки ввода вывода не закрывая его?
Хочу открыть файл записать в него строку, потом, не закрывая файл, начать запись заново, так чтобы старая информация удалилась:
std::ofstream file; file.open("file.txt", std::ios_base::in | std::ios_base::out); file
В результате получаю 1A а должно быть 1
Отслеживать
219k 15 15 золотых знаков 120 120 серебряных знаков 230 230 бронзовых знаков
задан 27 сен 2017 в 4:53
Rikitikitavi Rikitikitavi
2,409 4 4 золотых знака 20 20 серебряных знаков 37 37 бронзовых знаков
Вроде нельзя не закрывая файл
27 сен 2017 в 5:45
Если б было можно добраться до дескриптора файла, то может, мог бы спасти (нестандартный) chsize() .
27 сен 2017 в 5:53
1 ответ 1
Сортировка: Сброс на вариант по умолчанию
Стандартными средствами - никак.
Нестандартно - нужно получить файловый объект basic_filebuf с помощью rdbuf() , и в нем в конкретной реализации докапываться до файлового объекта - например, в VC++ - это закрытый член FILE* _Myfile . Если всяческими грязными хаками 🙂 добраться до него, то можно вызвать chsize(fileno(_Myfile)) . Но! это ОЧЕНЬ чревато неприятностями - как минимум работой через голову самого basic_filebuf , который, не подозревая о внесенных изменениях в состояние, может выдать совершенно неожиданное поведение.
Да и не стоит эта овчинка выделки. Зная, где должен заканчиваться файл - откройте новый и перепишите в него только нужное. Будет и надежнее, и проще.
Отслеживать
ответ дан 27 сен 2017 в 6:05
219k 15 15 золотых знаков 120 120 серебряных знаков 230 230 бронзовых знаков
- c++
- файлы
- fstream
-
Важное на Мете
Похожие
Подписаться на ленту
Лента вопроса
Для подписки на ленту скопируйте и вставьте эту ссылку в вашу программу для чтения RSS.
Дизайн сайта / логотип © 2024 Stack Exchange Inc; пользовательские материалы лицензированы в соответствии с CC BY-SA . rev 2024.1.26.3951
чистые данные внутри текстового файла в c++
Я программирую на C++. В моем коде я создаю текстовый файл, записываю данные в файл и читаю из него с помощью потока, после того, как я завершу последовательность, которую хочу, я хочу очистить все данные внутри txt файла. Может кто-то подсказать мне команду для очистки данных в txt файле. Спасибо
Поделиться Источник 10 июня 2013 в 21:12
5 ответов
Если вы просто откроете файл для записи с помощью опции усечения, вы удалите содержимое.
std::ofstream ofs; ofs.open("test.txt", std::ofstream::out | std::ofstream::trunc); ofs.close();
Поделиться 10 июня 2013 в 21:18
Насколько мне известно, просто открыв файл в режиме записи без режима добавления, будет стерто содержимое файла.
ofstream file("filename.txt"); // Without append ofstream file("filename.txt", ios::app); // with append
Первый будет размещать битовое местоположение в начале, стерв все содержимое, в то время как второй вариант будет размещать битовое местоположение в конце бита файла и записывать оттуда.
Поделиться 14 марта 2020 в 04:42
Если вы установите флаг trunc.
#include using namespace std; fstream ofs; int main() < ofs.open("test.txt", ios::out | ios::trunc); ofs
Я проверил это с трудом для своих собственных нужд в обычной ситуации программирования, в которой я столкнулся. Обязательно обязательно заранее выполните операцию ".close();". Если вы этого не делаете, нет никакого значения, вы trunc или просто примените к запросу файла. В зависимости от типа файла вы можете просто добавить файл, который в зависимости от ваших потребностей может не выполнить свою цель. Обязательно вызовите ".close();" явным образом в потоке, который вы пытаетесь заменить.
Поделиться 18 декабря 2016 в 15:15
Удаление файла также удалит содержимое. См. удаление файла.
Поделиться 10 июня 2013 в 21:35
Вам следует создать функцию, которая очищает все данные из файла, а затем запускает его.