Удалить запись из файла c
Для удобства обращения информация в запоминающих устройствах хранится в виде файлов.
Файл – именованная область внешней памяти, выделенная для хранения массива данных. Данные, содержащиеся в файлах, имеют самый разнообразный характер: программы на алгоритмическом или машинном языке; исходные данные для работы программ или результаты выполнения программ; произвольные тексты; графические изображения и т. п.
Каталог ( папка , директория ) – именованная совокупность байтов на носителе информации, содержащая название подкаталогов и файлов, используется в файловой системе для упрощения организации файлов.
Файловой системой называется функциональная часть операционной системы, обеспечивающая выполнение операций над файлами. Примерами файловых систем являются 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 в обычном формате.
Работа с файлами в языке Си
Для программиста открытый файл представляется как последовательность считываемых или записываемых данных. При открытии файла с ним связывается поток ввода-вывода . Выводимая информация записывается в поток, вводимая информация считывается из потока.
Когда поток открывается для ввода-вывода, он связывается со стандартной структурой типа 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, то нужно перенести строчку и начать вывод с новой строки. При этом пост вольный вывод не получится - придется использовать буфер (массив) для хранения следующего слова.
например я хочу удалить от туда запись Bobik или любую другую .
как можно сделать ? может сущетвует кой алгоритм удаления или надо мудрувать ?
Алгоритм зависит от того, по каким критериям ты будешь удалять запись: по номеру или по совпадению строк
Так что давай конкретнее
Алгоритм зависит от того, по каким критериям ты будешь удалять запись: по номеру или по совпадению строк
Так что давай конкретнее
впринцыпе все равно:p и вариант с удалением по сурагатному ключу или по совпаденю строк подходит
using namespace std;
int main()
ifstream in ("test.dat", ios::in);
ofstream out("test.new", ios::out);
char buff[256];
int num,i;
max_dark спасибо за код.
я наверлно не правильно обяснил, по номеру строки не подходит.
лучше уж по совпадению строки:)))
m_Valery Спасибо :)
с кодом разобрался, только не смог асилить что значит это:
Можешь вместо int _tmain(int argc, _TCHAR* argv[]) использовать
int main().int argc и _TCHAR* argv[]) - параметры командной строки. argc - количество параметров,argv - строки,представляющие отдельные значения. Смотри об этом подробнее в учебниках.В Visual Studio 2003,2005 используется int _tmain,в 6-й была просто main.
кстати а как вам такой вариант:
что на самом деле с файла ничего удалятся не будет
а только будут высавлястся статусы.
там где F то значит что они "мертвые".
а там где T то значит что они "живые".
а в самой проге будет функция которая проверяет статусы и работает только с "живыми" пользователями . и функция по удалению, которая по сути статусы меняет на F
кстати а как вам такой вариант:
что на самом деле с файла ничего удалятся не будет
а только будут высавлястся статусы.
там где F то значит что они "мертвые".
а там где T то значит что они "живые".
а в самой проге будет функция которая проверяет статусы и работает только с "живыми" пользователями . и функция по удалению, которая по сути статусы меняет на F
как такая идея, что скажите ?
main()
ofstream out("dogs.dat",ios::app);
char *name = new char[15];
char status;
в этом примере ты записываешь имя и статус, и читаешь имя и статус в отдельные переменные, и потом в цикле можешь сравнивать статус и вызывать функцию обработку с собаками
Можно функции read и write использовать, они записывают в файл структуры в текстовом виде, и соответственно могут удалять структуры
Помогите написать похожую прогу плз.
Программа должна удалять запись по совподению строк, но тока в файле в котором нужно удалить данные не один столбец, а 5.
Программа которая приведена в этой теме работает только если в файле один столбец.
Помогите написать похожую прогу плз.
Программа должна удалять запись по совподению строк, но тока в файле в котором нужно удалить данные не один столбец, а 5.
Программа которая приведена в этой теме работает только если в файле один столбец.
Построчно считываем файл в вектор.Вводим слово.которое хотим удалить,удаляем его и перезаписываем файл.Например так.
I have a hardlinked a file, and use File.WriteAllText , it seems as if this sometimes (?) deletes the file since the hardlinks are not kept updated.
I recommend you to do not do that if another operation will access the file right after this operation. I faced issue where the file didn't get closed write after this line of code, and cause IO exceptions of file is in use , so i recommend you to handle it manually through file stream
This is what I did to clear the contents of the file without creating a new file as I didn't want the file to display new time of creation even when the application just updated its contents.
Olive, if it answers your question, would you please mark it as an answer. However, if the proposed solution doesn't work in your case, please let us know even then.
+1 This is the only way to first acquire a file lock, check file attributes safely and finally clear the content.
This is exactly what i needed myself. i need to have a service communicate to an application for simple line-by-line messages to a user, and this allows me to keep my file lock and clear the messages to prevent the service app from inserting and inadvertently dropping messages or duplicating messages.
Wouldn't it be advisable to create the filestream in a using block? That would automatically close the stream as well.
Use FileMode.Truncate everytime you create the file. Also place the File.Create inside a try catch .
The easiest way is:
However, I recommend you use FileStream because the first solution can throw UnauthorizedAccessException
Try using something like
Creates or overwrites a file in the specified path.
Not a good idea for the question asked: Does not remove the data already in the file - it only overwrites it to the length of the new data, so if old data > new data you will end up with mix of the two.
The simplest way to do this is perhaps deleting the file via your application and creating a new one with the same name. in even simpler way just make your application overwrite it with a new file.
There can be problems if you try to create the file shortly after deletion. Sometimes the OS fails to create file as it "thinks" the file still exists.
@Dmitry Lobanov - [I know this is an old thread]. I do not accept that the operating system sometimes thinks a file still exists, unless there is a good reason. It would be a very poor OS if it did. MUCH more likely is that something still has a handle open on the existing file. It could even be your own software if you are not careful in closing files (by using 'using' for example to ensure disposal). Could be the anti-virus too. Agree with your conclusion though. I think FileMode.Truncate is the way to go.
Необходимо удалить все элементы, у которых год выпуска меньше заданного.
Вот код: создаёт файл и мы записываем туда структуру, но мне надо потом ввести год и программа должна удалить все строки, у которых год выпуска меньше заданного. Как это сделать?
1) Открываем файл с записями (ф1) на чтение. 2) Открываем новый файл (ф2) на запись. 3) читаем по очереди записи из ф1, если запись удовлетворяет условию (например год больше заданного), записываем запись в ф2. 4) закрываем файлы и заменяем ф1 на ф2.
Отформатируйте как следует и хватит плодить одинаковые вопросы, вы там за всю группу задания постите что ли?
Вам уже объясняли основной алгоритм: 1) Открываем файл на чтение. 2) читаем по очереди строки из файла, если строка удовлетворяет условию, записываем её в во временную строковую переменную. 3) закрываем файл 4) открываем тот же файл на перезапись, записывам полученную в пункте 2 строку.
Ах да, самое главное забыл, вы хоть добавьте в описание вопроса разяснение проблемы, что именно в коде не работает? Ну или хотя бы опишите словами то, что код должен делать и вам быстро напишут какой-нибудь вариант решения (просто ваши вопросы очень размытые мягко говоря). И, все-таки, отформатируйте код в вопросе.
3 ответа 3
Как-то так, только проверьте, давно ничего не читал из файлов.
Точку с запятой расставили (я там пропустил в паре мест)? На какие скобки? Этот код должен быть внутри main, ну и Ваш outfile закрыть нужно сначала.
Ну, первая ошибка - комментарий начинается с // , а не \\ :)
А вторая и главная - вы объявили record.year как string , но сравниваете это поле с int . Что больше - "литр" или 15? - примерно так у вас получилось.
Это ответ на ваш конкретный вопрос, но это еще не все ошибки. Намекну, например, что при объявлении массива его размер должен быть известен при компиляции.
@Софья Ну я же указал вторую. третья - думаю, стоимость тоже не стоит делать строкой. Далее, если вы попробуете ввести как марку машины, например, Volkswagen Passat - как два слова - то второе слово окажется ценой. Думаю, пока хватит.
Начнем с мелочи - вы пишете в файл, открытый для чтения. Но это мелочь. Посмотрите сами, что делает ваша программа во второй части: считывает и выводит кучу записей из файла (надеюсь, что он есть и не пуст. ), затем пытается проверить последнюю (не помню уж, формально - не имеет ли права fread испортить память при ошибке чтения), и если она проходит условие - пытаетесь дописать ее в конец файла, открытого для чтения. "Где же логика?!" (с) Анекдот про Вовочку.
И еще - если вы так пишете код, не форматируя - вы мешаете сами себе. Поймите, всякие отступы и т.п. - это не придирки преподавателя. Согласитесь, что такой код, как показан ниже, гораздо проще понимать. А современные редакторы по сути сами его делают таким (вопрос скорее - как вам удается так его корежить?)
fopen – функция, обращающаяся к операционной системе, чтобы получить дескриптор файла с указанными именем. Кроме имени файла, необходимо указать режимом работы с ним.
Имя файла
Файл всегда ищется в той папке, из которой была запущена программа. Если необходимо указать файл, находящийся в другой папке, то нужно указать его с помощью абсолютного или относительного пути.
Абсолютный (полный) путь: “D:/some-folder/some-file.txt” – указание диска и всех папок
Относительный путь: “../some-folder/some-file.txt” – используя символ “..” можно подняться на уровень выше (выйти из текущей папки). Обычно используется если необходимый файл находится на том же диске в соседней/родительской папке. Символов “..” можно указывать столько, сколько необходимо: “../../../../some-file.txt”
Знание про абсолютный и относительный пути пригодится тебе в любом языке и любой операционной системе – запомни это.
Режим работы с файлом
Всего есть 3 основных режима:
- “r” – чтение. Открываем существующий файл и вычитываем оттуда данные.
- “w” – запись. Создаём новый файл (если такой уже есть, то перезаписываем его) и записываем туда данные.
- “a” – запись в конец. Открываем существующий файл (если файла ещё нет, то создаём его) и записываем данные в конец файла.
К этим режимам можно дописать “+”, чтобы разблокировать возможность чтения для “w” и “a”, и возможность записи для “r”.
Вот табличка, в которой я собрал все комбинации
Режим | Чтение | Запись | Создать новый файл (если нет) | Очистить содержимое |
---|---|---|---|---|
“r” | + | - | - | - |
“w” | - | + | + | + |
“a” | - | + | + | - |
“r+” | + | + | - | - |
“w+” | + | + | + | + |
“a+” | + | + | + | - |
Их не нужно запоминать – обычно все пользуются:
- “r” при чтении
- “w” при записи
- “r+” при чтении/записи
Но если в какой-то ситуации тебе понадобится что-то другое – не стесняйся экспериментировать.
fclose – функция принимает дескриптор открытого файла, и закрывает его, записывая все данные из буффера.
Стоп, что за буффер?
FILE – это не дескриптор
Я был не до конца честен, когда говорил, что FILE – это дескриптор файла. На самом деле, FILE это обёртка над настоящим дескриптором.
Чтобы получить настоящий дескриптор, в зависимости от операционной системы, надо использовать функции:
Обёртка над дескриптором FILE поддерживает:
- Буфферизацию – то есть не сразу записывает все данные в файл, а ждёт пока накопится достаточное количество данных во временном буффере (который хранится в оперативной памяти)
- Отслеживание позиции – благодаря этому мы можем удобно узнать дошли ли мы до конца файла при чтении
- Обработку ошибок – можно узнать произошла ли ошибка при выполнении чтения/записи с помощью функции ferror
Подробнее про разницу между FILE и дескриптором можно прочитать тут.
Закрываем FILE
Окей, с закрытием FILE разобрались – при закрытии в файл записывается буффер.
Когда это делать? Когда закончили работать с файлом.
Что будет если это не сделать?
Если программа завершается как обычно, то ничего плохого не произойдёт – перед закрытием наша программа запишет буффер в файл и закроет дескриптор файла.
В случае, если программа упадёт до закрытия FILE – в файл ничего не запишется, так как буффер не успел записаться в файл. Однако дескриптор закроется, но не программой, а операционной системой (потому что получившая его программа умерла). Вот пример такой ситуации:
Если бы мы закрыли файл до падения, то всё было бы хорошо в этом случае. В общем – всегда следи за закрытием.
Можно записать буффер в файл до закрытия с помощью функции fflush. Если я вызвал бы её до падения в программе выше, то данные бы записались в файл.
Для записи в файл в библиотеке “stdio.h” есть ряд функций:
- fprintf – записываем текст в файл, указывая строку форматирования (как в обычном printf)
- fputc – записать один char в файл
- fputs – записать строку (всё до ‘\0’) в файл
- fwrite – записать массив значений (с указанным размером элемента и количеством элементов) в файл
Для записи там есть альтер-эго таких же функции:
- fscanf – считываем текст из файла, указывая строку форматирования (как в обычном scanf)
- fgetc – считать один char из файла
- fgets – считать строку из файла. Считывается всё до конца файла или символа переноса строки ‘\n’. Символ переноса строки включается в результирующую строку
- fread – считать массив значений (с указанным размером элемента и количеством элементов) из файла
Давайте я напишу программу, которая “шифрует” все символы в файле, а потом “дешифрует” их.
“Шифрованием” у меня будет смещение кода символа на 1, а “дешифрацией” – смещение кода символа на -1.
При этом, будет необходимое условие – в начале файла должен стоять символ ‘0’.
Программа изменяет так:
При повторном запуске программы, файл возвращает исходный вид.
Если что, это “шифрование” сможет защитить только от человека, который не является IT-специалистом. В настоящем шифровании каждый символ шифруется с использованием сложных криптографических алгоритмов и длинного уникального секретного ключа (один из них – алгоритм RSA).
Так, в этой программе я использовал какие-то функции feof и fseek – что это?
Благодаря обёртке FILE, у нас есть возможность перемещаться по файлу, смещая указатель позиции файла.
Изначальная позиция
У каждого FILE есть свой указатель позиции файла, изначальная позиция которого зависит от режима работы с файлом, который мы использовали:
После этого, при чтении/записи указатель позиции будет смещаться вперёд на:
- 1 символ для fgetc и fputc
- Количество символов строки для fgets и fputs
- Количество символов форматированного ввода/вывода для fscanf и fprintf
- (Размер_элемента * количество_элементов) символов для fread и fwrite
Сдвигаем позицию
Также, есть функция fseek, которая смещает текущий указатель позиции на указанное количество символов, относительно некоторой позиции.
“Некоторая позиция” также указывается параметром:
- SEEK_CUR – текущая позиция
- SEEK_SET – начало файла
- SEEK_END – конец файла
ВАЖНО: кроме перемещения по файлу, необходимо вызывать fseek, если ты хочешь переключиться с режима чтения на режим записи, в комбинированных режимах, вроде “r+”, “w+” и “a+”. В программе выше я для этого вызываю fseek без смещения.
Значение текущего указателя позиции можно получить через функцию ftell
Проверяем, что дошли до конца файла
Для проверки того, что мы дошли до конца файла, необходимо вызвать функцию feof.
Эта функция возвращает 1, если указатель позиции дошёл до конца файла.
feof вернёт 1 только в случае, если мы перед этим вызвали функцию чтения, которая дошла до конца файла (fgetc, fgets, fscanf, fread).
Это происходит из-за того, что функция чтения, при упирании в конец файла, выставляет флажок “достигли конца файла”, который и проверяет функция feof.
Также, при вызове функций чтения, по возвращаемому значению можно понять что мы дошли до конца файла:
- fgetc – вернёт -1, если дошли до конца файла; вместо -1 в этом случае используется константа EOF (End Of File)
Обычно fget возвращает код символа от 0 до 255
- fscanf – вернёт количество считанных элементов, отличающееся от требуемого (упёрлись в конец файла)
- fread – вернёт количество считанных элементов, отличающееся от требуемого (упёрлись в конец файла)
Это последняя тема, которую я хочу объяснить.
У функции fopen есть ещё один режим работы – бинарный файл.
Для того, чтобы открыть файл в бинарном виде, надо указать “b” в конце строки, определяющей режим работы с файлом:
Режим работы при этом может быть любым.
Теперь мы работаем с файлом не как с текстом, а как с набором байт.
То есть, я могу создать массив int, записать его в файл, а потом считать оттуда:
Возможно ты думаешь, что в файле сейчас записано что-то вроде “1 2 4 8 16”, но нет – там такое:
Оно выглядит так странно из-за того, что текстовый редактор не может нормально отобразить бинарные данные – он пытается прочитать коды символов.
Чтобы реально узнать что там лежит, необходимо воспользоваться редактором, который может отображать бинарные данные. Вот как содержимое выглядит через такой редактор:
Обычно они называются hex-editor, потому что отображают данные в шеснадцатеричной системе счисления. Посмотрев на данные в представлении этого редактора, можно заметить что наши 5 int’ов лежат там как ни в чём не бывало.
Зачем вообще это надо? Почему нельзя хранить всё как текст?
Представь, что я захочу сохранить unsigned int число 4294967295:
- В бинарном файле это число всё так же займёт 4 байта (FF FF FF FF)
- В текстовом файле это число займёт 10 байт (в этом числе 10 символов) + дополнительная нагрузка при чтении данных, так как надо перевести строку в unsigned int
Про хранение вещественных чисел я вообще молчу
Если численные данные в базах данных хранились бы текстом, то понадобилось бы в 2+ раз больше дата-центров.
В общем, если пользователю не надо напрямую взаимодействовать с текстом в файле, то бинарные файлы – это отличный вариант.
Как работать с русскимим символами?
Надо добавить поддержку русской локализации:
И убедись, что ты сохраняешь файл в кодировке “windows 1251” – обычно файлы сохраняются в кодировке UTF-8. Так как кодировка UTF-8 двухбайтная (каждый символ кодируется двумя байтами), ты не сможешь работать с нимми как обычно.
Как перевести строку в число?
Здесь можешь посмотреть документацию к различным функциям перевода строки в число:
- atoi() – строка в int
- atof() – строка в double
- atol() – строка в long int
Функции strtof, strtod, strtol и подобные, тоже переводят строку в число, но обладают расширенной функциональностью – смотри в документацию.
Обратное преобразование возможно через sprintf и fprintf.
Можно ли удалить из файла какие-то символы/слова?
Нет, нельзя – это можно сделать одним из двух способов:
- Считать файл во временный буффер, удалить из буффера слова/символы и перезаписать файл с флагом “w” новым содержимым
- Создать временный файл, считывать символы/слова из исходного файла, записывать (если символ/слово подходит) во временный файл, в конце удалить исходный файл и переименовать временный так, чтобы он назывался как исходный.
Вот пример использования первого способа, для решения задачи “удалить слово mother из файла”:
Как изменить символы в файле?
Открыть файл в режиме “r+”, считывать, смещаться fseek’ом на символ назад, записывать новое значение.
В главе “Чтение/запись в файл” есть пример.
Итого, ты узнал что такое:
- Файл
- Дескриптор
- Открытие файла
- Закрытие файла
- FILE – это обёртка надо дескриптором
- Функции чтения и записи
- Перемещение указателя позиции по файлу
- Определение конца файла
- Бинарные файлы
Поздравляю, это супер-круто! Это сложная тема, и скорее всего всё сразу не уляжется в голове – попробуй написать пару программ, перечитать непонятные места и отдохнуть.
Читайте также: