znow operacja na plikach - PILNE

0

jest plik tekstowy, sklada sie z jednego wiersza i powiedzmy ze wyglada tak:

jakisTekstWPlikuTekQQQstowym

problem:
w jaki sposob (najlepiej uzywajac strumieni) usunac 3 znaki 'Q'. wiem ze moge wczytac to do pamieci, poprawic i zapisac do pliku po jego wczesniejszym wyczyszczeniu z zawartosci - ale to rozwiazanie nie jest dobre. bo co gdyby plik ial 999999 wersow po 3333333 znakow w kazdym. strata czasu i zasobow. moge to zrobic jakos bezposrednio na pliku? po prostu wykasowac z tamtad tylko te znaki?

za szybka odpowiedz dziekuje. jest mi to pilnie potrzebne a nie moge wpasc na pomysl jak to rozwiazac.

0

wczytuj plik znak po znaku . i sprawdzaj warunek czy aktualnie wczytany znak to nie jest Q jeżeli jest to omijaj i wczytuj kolejne znaki po czym zapisuj wszystko .

0

mam jeszcze jeden problem. oto kawale kodu:

fstream strumienPliku("dane.txt", ios::out | ios::ate | ios::binary);
strumienPliku.write("SSS", 3);

wyczytalem ze przy uzyciu ios::ate wskaznik zapisu/odczytu ustawiany jest na koncu pliku i nie jest kasowana zawartosc pliku. tyle ze u mnie jest kasowana cala zawartosc pliku i dopiero jest dopisywane co trzeba. wiem ze jest ios::app ale to nie pozwala na zapis w srodku pliku (jak ustawiam .seekp na cos w srodku pliku to i tak dodaje na koniec). jak moge dodac cos do srodka pliku?

i co do przeszukiwania znak po znaku. to bedzie dobry sposob o ile wczytam CALY plik, skasuje jego zawartosc i dopiero zapisze. ale ja chcialbym tego uniknac jesli sie da, bo jesli plik bedzie ogromny to wtedy bedzie to wolne i zasobozerne rozwiazanie. potrzebuje jakiegos innego rozwiazania. a moze mozna usunac z pliku cos od pewnej pozycji az do jego konca? lub moze wstawic w jakis sposob (jak tak to jaki) koniec pliku w jakiejs pozycji w pliku. A jesli to z przepisywaniem calego pliku jest jedynym rozwiazaniem to napiszcie mi ze inaczej sie nie da.

dzieki piekne

0

najlepiej otworz plik z którego chcesz czytać, i otworz drugi do zapisu. i teraz wczyttuj znak po znaku i albo go odrzucasz, albo zapisujesz do drugiego pliku. albo czytaj po np. 1000 bajtów, przeglądaj cały ten kawałek w pamięci, usuwaj itp, i potem zapisuj do pliku to co zostało, i tak do końca pliku.
Jak już przerobisz w ten sposób cały plik wejściowy, to skasuj go i zmien nazwę tego pliku do którego zapisywałeś. Nistety ma to też wady - jeśli plik jest duży i usuwasz z niego mało, to na końcu na dysku będzisz miał dwa takie duże pliki...

W sumie to chyba powinno działać też coś takiego, że otwierasz plik do zapisu i odczytu jednoczesnie, czytasz znak po znaku i idziesz wskażnikiem odczytu (i zapisu) do przodu. Jak natrafisz na pierwsze Q to przestawiasz wksaźnik odczytu o jeden do przodu, a zapisu nie. i od tego moementu robisz tak:
wczytaj znak;
jesli nie Q to:
zapsiz znak tam gdzie wskaznik zapisu;//czyli wczesniej niż odczytu
else
przestaw wskaźnik odczytu o jeden do przodu;//ale nie przestawiaj wskaźnika zapisu

w ten sposób będziesz przepisywał cały plimk bez wczytywania go do pamięci i bez tworzenia drugiego.
Wydaje mi sie, że takie coś powinno działać, ale nie sprawdzałem.
Pozdrawiam

0

mam jeszcze jeden problem. oto kawale kodu:
fstream strumienPliku("dane.txt", ios::out | ios::ate | ios::binary);
strumienPliku.write("SSS", 3);

Spróbuj zrobić raczej tak:

fstream Plik("c:\\logping.txt",  ios::ate | ios::in | ios::out | ios::binary);

Tak raczej nie powinien się kasować :)...

0

to drugie rozwiazanie nie jest dobre. myslalem wczesniej tez nad nim. problem polega tu na tym ze jak juz "nadpisze" plik z danymi (w naszym przykladzie pomijajac znaki 'Q') to zostana na koncu "smieci" (od miejsca gdzie zapisalem ostatni znak do konca pliku). "smieciami" tymi beda pozostalosci po nienadpisanych danych (w naszym przykladzie 3 ostatnie znaki z wersji przed poprawieniem). moze ma ktos jakies inne sugestie?
I CO Z TRYBEM IOS::ATE ??

0

dzieki krecik. nie kasuje wtedy pliku, ale nie dziala tez za dobrze. dlaczego? spojrzcie na kawalek kodu:

fstream strumienPliku("dane.txt", ios::in | ios::out | ios::ate | ios::binary);
strumienPliku.write("TTT", 3);
strumienPliku.put('e');

w pliku sa jakies wpisy (dodalem je recznie). po wykonaniu tego co jest powyzej powinno byc dopisane do pliku TTTe w ostatniej linijce. Tyle ze mi dopisuje jakies dziwne prostokaciki zamiast tych znakow. Jest to niezalezne od tego czy mam wlaczone ios::binary czy nie. jak nie podam ios::in to dopisuje dobrze ale kasuje plik. o co tu chodzi?
uzywam visual studio c++ .net.

pomozcie i nie pozwolcie by byl to monolog !!!
dzieki

0

To dziwne… U mnie (w Borland C++ Builder 6.0 Personal) dziła bardzo dobrze, oto kod jakim testowałem:

fstream strumienPliku("c:\\logping.txt", ios::in | ios::out | ios::ate | ios::binary);
char *text = "TEST KrEcIk TEST";
strumienPliku.write(text, strlen(text));
strumienPliku.put('!');
strumienPliku.close();

Jest dobrze nawet wtedy, kiedy nie zamknę pliku...

0

a w jaki sposob zmienic nazwe pliku dyskowego ?
na tym zakoncze polemike.

0

to drugie rozwiazanie nie jest dobre(...)

Owszem pozostaja znaki na końcu, ale wtedy możesz do końca pliku isć i nadpisywac te znaki np. enterami....
A do zmiany nazwy pliku możesz wykorzystać funkcję Api FileMove czy jakoś tak

0

Do zmiany rozmiaru pliku służy np. chsize() z io.h

1 użytkowników online, w tym zalogowanych: 0, gości: 1