Файловый вывод в определенное место
у меня есть файл qwer.h. В нём написано hello, misha. Я хочу добавить слово dear после hello.
#include <iostream>
#include <fstream>
int main()
{
std::ofstream ff1{"qwer.h", std::ios::ate};
ff1.seekp(5, std::ios::beg);
ff1 << "dear" << std::endl;;
return EXIT_SUCCESS;
}
В итоге, в файле qwer.h я получаю следующее: ^@^@^@^@^@dear. Я пробовал поменять std::ofstream ff1{"qwer.h", std::ios::ate}; на std::ofstream ff1{"qwer.h", std::ios::ate | std::ios::app};, но тогда слова просто добавляются в конец файла.
Ответы (1 шт):
Вот здесь можно почитать про флаги открытия потока: https://en.cppreference.com/w/cpp/io/ios_base/openmode
Если кратко описать суть, то std::ios::app вам никак не поможет, т.к. при установленном этом флаге перед каждой операцией записи курсор будет установлен в конец потока, независимо от того куда вы перемещали его раньше. std::ios::ate также устанавливает курсор в конец потока при его открытии, но не перемещает его туда при записи. Так как вы открыли поток только с эти флагом, то программе ничего не известно о том, какие данные уже есть в этом потоке, поэтому, после ff1.seekp(5, std::ios::beg); он переставляет курсор на пять символов от начала и после выполнения строки ff1 << "dear" << std::endl; Заполняет первые 5 символов нулями и перезаписывает остальное.
Для того, чтобы вставить текст в нужное место, вам нужно добавить флаг std::ios::in, т.е. должно получится так: std::ofstream ff1{ "qwer.h", std::ios::in | std::ios::ate };.Это позволит программе получить уже имеющиеся данные в потоке. Хотя, по большому счету, std::ios::ate вам даже не нужен, т.к. вы считаете от начала, а не от текущей позиции. В итоге открыть поток можно так: std::ofstream ff1{ "qwer.h", std::ios::in | std::ios::out };. Флаг std::ios::out разрешает запись в поток. Однако это все равно не даст вам желаемого результата, т.к. у вас сохранятся первые пять символов потока, далее заменятся 4 символа на dear и выведется остаток потока. Т.е. вы получите что-то наподобие: Hellodearha. Для того чтобы именно вставить новые символы с сохранением остальных, правильнее всего будет использовать временный поток, в котором вы сформируете полностью все что вам нужно, а потом скопируете в целевой.
P.S. надеюсь понятно объяснил :)