• Najnowsze pytania
  • Bez odpowiedzi
  • Zadaj pytanie
  • Kategorie
  • Tagi
  • Zdobyte punkty
  • Ekipa ninja
  • IRC
  • FAQ
  • Regulamin
  • Książki warte uwagi

Zapis do pliku bez usuwania danych

VPS Starter Arubacloud
+3 głosów
1,685 wizyt
pytanie zadane 30 czerwca 2015 w C i C++ przez Phobos Użytkownik (720 p.)
Witam, mój problem polega na tym, że chcę w c++ zapisać dane do pliku, jednakże zwyczajne plik.open("plik.txt", ios::out);   a potem  plik << "tekst";   skutkuje tym, że dane, które już były w pliku zostaną usunięte a nowe zapisane.   Jednakże opcja  ios::app   też nie daje rady, bo ona dopisuje na końcu pliku, lecz ja potrzebuje dane dopisywać na początku a stare usuwać, ale reszta żeby została bez zmian. Pomocy ..

4 odpowiedzi

0 głosów
odpowiedź 30 czerwca 2015 przez Dorion300 Szeryf (90,250 p.)
Użyj "ios::app" zamiast "ios::out"
komentarz 30 czerwca 2015 przez Phobos Użytkownik (720 p.)
Przecież napisałem, że ios::app mi nie wystarcza, bo app dodaje do końca pliku, a ja chce w konnkretnym miejscu albo na początku pliku.
komentarz 30 czerwca 2015 przez Dorion300 Szeryf (90,250 p.)
Jeśli chcesz na początku to zmieniasz "kursor" za pomocą seekg(0) i seekp(0) i wtedy będzie dopisywalo na początku Np. Plik.seekg(0); Seekg ustawia kursor do odczytywanie. A seekp ustawia kursor do Zapisywania
komentarz 30 czerwca 2015 przez MrWeb Stary wyjadacz (10,200 p.)
Tak, ale po przesunięciu kursora i zapisaniu do pliku nowych danych nadpisujemy stare dane tekstowe...
komentarz 30 czerwca 2015 przez Dorion300 Szeryf (90,250 p.)
No to jedyną moźliwą rzeczą jest wczytanie całego pliku w zmienną. (string)
I operowaniu na nim.
komentarz 30 czerwca 2015 przez MrWeb Stary wyjadacz (10,200 p.)

Tak, ale trzymanie całego pliku tekstowego w pamięci jest niepraktyczne, bo jeśli tym plikiem jest jakiś log systemowy to będzie miał kilka tysięcy linii co przekłada się na RAM-o-żerność programu wink

Lepiej będzie zapisać do nowego pliku nowe dane, a potem po linijce odczytywać dane z starego pliku i zapisywać je do nowego. Ale z drugiej strony potrwa to napewno dłużej bo takie odczytywanie pliku po linijce nie jest zbyt wydajne.

komentarz 30 czerwca 2015 przez Phobos Użytkownik (720 p.)
No to tak słuchajcie xd:

Tak wiem, że plik nie będzie możliwy do otwarcia (o to chodzi hehe).

Nie wiem czy ktoś z was kiedyś próbował modyfikać plik exe w trybie tekstowym, jeśli nie to powiem, że plik .exe na początku posiada napis "MZ", jeśli dajmy na to usuniemy ten napis i zapiszemy plik jako .exe to plik nie będzie działał, ale jeśli znowu edytujemy plik .exe i dopiszemy "MZ" i zapiszemy jako .exe to plik znowu zacznie działać. Tylko, że warunkiem jest nie zmienianie rozszerzenia pliku, tzn. jeśli edytujemy plik exe usuniemy MZ i zapiszemy jako txt, potem znowu edytujemy dopiszemy MZ i zapiszemy jako .exe to plik nie będzie działał. Dlatego kopiowanie całości odpada z pomysłu.
komentarz 30 czerwca 2015 przez Dorion300 Szeryf (90,250 p.)
Logi systemowe są takie że najstarsze są w pierwszych linijkach A te najnowsze w ostatnich linijkach. Zauważyłem też że Steam także tak robi.
komentarz 30 czerwca 2015 przez MrWeb Stary wyjadacz (10,200 p.)
edycja 30 czerwca 2015 przez MrWeb
Logi w systemie Linux są zbudowane w ten sposób, że najnowsze wpisy są najniżej w pliku (na końcu).

Dla przykładu plik dpkg.log z wczoraj ma łącznie 64709 bajtów.. Niby nic dla dzisiejszych pamięci RAM ale to jednak sporo jak na mały plik log...

 

Jeśli chcesz tylko zmodyfikować te dwie litery MZ to:

Wczytujesz cały plik do tablicy typu unsigned char o rozmiarze tego pliku

Modyfikujesz te dwie litery MZ na powiedzmy BM (to jest dla plików .bmp)

Zapisujesz całą tablicę bajtów spowrotem do tego samego pliku nadpisując stare wartości

Zamykasz plik

 

O takie coś Ci chodziło? :)
komentarz 30 czerwca 2015 przez Phobos Użytkownik (720 p.)
Właśnie niestety nie chce zmodyfikować tylko MZ, jak bym chciał tylko te dwa pierwsze znaki to bym zrobił najprościej jak to możliwe, wystarczy plik << "DB"; i tyle xd, tylko że ja nie będę modyfikował tylko plików exe xdd, na MZ zaczynają się tylko niektóre pliki np. DLL .. ale np pliki .o .mpeg, jpeg iwgl mają inne symbole początkowe i tu jest problem, że nie zawsze będę wiedział jakie to będą więc strzelanie na ślebo że to będzie MZ nie wchodzi w gre. Dlatego wolałbym dopisać na początku pliku jakiś string bez zmiany czegokolwiek.
0 głosów
odpowiedź 30 czerwca 2015 przez Eryk Andrzejewski Mędrzec (164,260 p.)
Może wczytaj dane z całego pliku do np tablicy, podmień jej odpowiedni element, ten który chcesz zamienić i zapisz do pliku o tej samej nazwie całą zawartość tablicy :)
0 głosów
odpowiedź 30 czerwca 2015 przez MrWeb Stary wyjadacz (10,200 p.)
Nie można tego zrobić w bezpośredni sposób. Najlepszym rozwiązaniem będzie:

1. Stworzenie nowego pustego pliku tekstowego

2. Zapisanie do tego pliku nowych linijek (te które chciałeś dodać na początek)

3. Otworzenie starego pliku tekstowego

4. Wczytanie całej zawartości starego i skopiowanie do nowego pliku

5. Zamknięcie i usunięcie starego pliku tekstowego

6. Zmiana nazwy nowego pliku tekstowego na starą nazwę (tego z pkt 5) i zapisanie pliku.
komentarz 30 czerwca 2015 przez Phobos Użytkownik (720 p.)
Koledzy, wszystko fajnie iwgl, ale mi nie chodzi o edycje zwykłych plików tekstowych hehe, dziwnie to zabrzmi ale raczej o edycje plików .exe a jak wiadomo plik exe po edycji nie da się skopiować, bo zawiera znaki różne od edytora tekstu, więc motyw z zapisaniem całości do tablicy odpada. Nie ma takiej opcji, żeby poprostu dopisać dane ale na początku pliku, bez zastępowania tych danych? poprostu dopisanie a reszta żeby się niejako przesunęła o tą ilość w tył.
komentarz 30 czerwca 2015 przez MrWeb Stary wyjadacz (10,200 p.)

W opisie problemu jest kod plik.open("plik.txt", ios::out); dlatego myślałem, że chodzi Ci o pliki tekstowe. 

Z execami może być problem bo pewnie się nie uruchomią po dopisaniu danych w pliku... ale zawsze można spróbować ;)

Musiałbyś wczytać plik do takiej fajnej strukturki i na niej operować dopisywaniem danych. Ale to już wykracza poza moje umiejętności.

https://en.wikibooks.org/wiki/X86_Disassembly/Windows_Executable_Files

komentarz 30 czerwca 2015 przez MrWeb Stary wyjadacz (10,200 p.)
Chyba że chesz po prostu otworzyć plik "na twardo" i na samym początku wkleić dane, wtedy wystarczy ten sposób który opisałem w punktach u góry, ale ostrzegam - na 100% nie będziesz mógł uruchomić takiego pliku po edycji.
–1 głos
odpowiedź 9 lipca 2019 przez koraz Nowicjusz (140 p.)

Ten post jest stary, ale wyświetla się na pierwszych pozycjach w google, a tyle tu głupich odpowiedzi można wyczytać, że aż przykro. Tymczasem rozwiązanie okazuje się być bardzo proste. Wystarczy zrobić uchwyt do odczytu i zapisu jednocześnie.

Jedyne co, to istotne jest to to że tym sposobem można jedynie nadpisywać znaki. Jeżeli np. jakaś liczba zmieni się z 8 na 12 to masz problem bo to nie jest notatnik, że ci ładnie rozepchnie całą resztę dla dodatkowego znaku.

 

std::fstream plik;
plik.open("C:\\Twoja\\ścieżka\\do\\pliku.txt", std::ios::in|std::ios::out);
plik.seekp(5, std::ios::cur); //Przesuń pozycję kursora do zapisu o 5 znaków w prawo
plik<<zmienna_ktora_chcesz_zapisac<<std::endl;
plik.close();

 

komentarz 9 lipca 2019 przez DragonCoder Nałogowiec (36,500 p.)

Jedyne co, to istotne jest to to że tym sposobem można jedynie nadpisywać znaki. 

Autor chcial cale linijki tekstu, a nie tylko pojedyncze znaki to raz

2. Twoja propozycja padla u gory

Jeśli chcesz na początku to zmieniasz "kursor" za pomocą seekg(0) i seekp(0) i wtedy będzie dopisywalo na początku Np. Plik.seekg(0); Seekg ustawia kursor do odczytywanie. A seekp ustawia kursor do Zapisywania

 

 

komentarz 9 lipca 2019 przez koraz Nowicjusz (140 p.)

Może i całe linijki tekstu, to bez znaczenia.Byleby długość nowej wstawki się zgadzała

2. Twoja propozycja padla u gory

No właśnie chodzi o to że nie. Samo używanie  seekp(0,std::ios::beg) w połączeniu ::app i tak ustawi kursor na końcu dotychczasowej treści pliku, zaś samego ::out całkowicie ją kasuje.

Podobne pytania

0 głosów
2 odpowiedzi 490 wizyt
pytanie zadane 14 lipca 2020 w C i C++ przez Kxmil Nowicjusz (220 p.)
0 głosów
1 odpowiedź 340 wizyt
pytanie zadane 3 grudnia 2020 w C i C++ przez Mateusz1223 Bywalec (2,440 p.)
+1 głos
0 odpowiedzi 116 wizyt
pytanie zadane 12 czerwca 2020 w C i C++ przez amtrax Dyskutant (9,630 p.)

92,455 zapytań

141,263 odpowiedzi

319,100 komentarzy

61,854 pasjonatów

Motyw:

Akcja Pajacyk

Pajacyk od wielu lat dożywia dzieci. Pomóż klikając w zielony brzuszek na stronie. Dziękujemy! ♡

Oto polecana książka warta uwagi.
Pełną listę książek znajdziesz tutaj.

Akademia Sekuraka

Akademia Sekuraka 2024 zapewnia dostęp do minimum 15 szkoleń online z bezpieczeństwa IT oraz dostęp także do materiałów z edycji Sekurak Academy z roku 2023!

Przy zakupie możecie skorzystać z kodu: pasja-akademia - użyjcie go w koszyku, a uzyskacie rabat -30% na bilety w wersji "Standard"! Więcej informacji na temat akademii 2024 znajdziecie tutaj. Dziękujemy ekipie Sekuraka za taką fajną zniżkę dla wszystkich Pasjonatów!

Akademia Sekuraka

Niedawno wystartował dodruk tej świetnej, rozchwytywanej książki (około 940 stron). Mamy dla Was kod: pasja (wpiszcie go w koszyku), dzięki któremu otrzymujemy 10% zniżki - dziękujemy zaprzyjaźnionej ekipie Sekuraka za taki bonus dla Pasjonatów! Książka to pierwszy tom z serii o ITsec, który łagodnie wprowadzi w świat bezpieczeństwa IT każdą osobę - warto, polecamy!

...