kilopierogow Temat założony przez niniejszego użytkownika |
[C++] Usuwanie znaku z pliku » 2017-01-15 20:30:52 Witam, Jak w temacie, oto kod : #include <iostream> #include <fstream> #include <iomanip> #include <string> #include <cstdlib>
using namespace std;
int main() { fstream plik; cout << "nazwa podaj" << endl; string nazwa; cin >> nazwa; int znak_usun; cout << "Ktory znak chcesz usunac?"; cin >> znak_usun; ofstream temp; plik.open( nazwa.c_str(), ios::in | ios::binary ); if( !plik ) { cout << "Plik wejsciowy nie zostal otwarty\n"; return 1; } temp.open( "temp.dat", ios::out | ios::binary ); if( !temp ) { cout << "Plik wyjsciowy nie zostal otwarty\n"; return 1; } int dlugosc_pliku; while( !plik.eof() ) { dlugosc_pliku++; } unsigned char * tablica = new unsigned char[ dlugosc_pliku ]; for( int i = 0; i < dlugosc_pliku; i++ ) { plik.read( reinterpret_cast < char *>( tablica ), dlugosc_pliku ); if( i != znak_usun ) temp << static_cast < char >( tablica[ i ] ); } delete[] tablica; plik.close(); temp.close(); remove( nazwa.c_str() ); rename( "temp.dat", nazwa.c_str() ); return 0; }
Program tworzy temp.dat, ale nic poza tym. Nie chce przepisywać z pliku do tempa. Jakieś uwagi? Pozdrawiam. |
|
mokrowski |
» 2017-01-15 21:16:46 Wbrew pozorom nie takie głupie pytanie jak się wydaje na początku. Co chcesz osiągnąć? Czyli jak ten program ma działać (co zrobić)? |
|
kilopierogow Temat założony przez niniejszego użytkownika |
» 2017-01-15 21:28:41 W pliku mam ciąg znaków, bez jakiegoś podziału na linie czy coś. Użytkownik podaje indeks znaku do usunięcia. Program otwiera nowy plik, przepisuje całość danych ze starego pliku, pomijając znak który podał użytkownik. Usuwany jest stary plik, a nowemu jest zmieniana nazwa by "imitował" stary. Przeszukując polskie i anglojęzyczne fora nie znalazłem innej opcji niż przepisanie całego pliku.
Wydaje mi się że jest to banalnie proste, tylko walnąłem się gdzieś w formułowaniu kodu. Pozdrawiam. |
|
mokrowski |
» 2017-01-15 21:39:46 Dziś odpowiadałem na podobny problem. Tu zacytuję kod który nie rozwiązuje bezpośrednio Twojego problemu ale pokazuje ideę pracy z pozycjami w pliku i użycie tellg() oraz seekg(). Jeśli nie zainspiruje Cię to do rozwiązania, zadaj pytanie ponownie. Dość że wystarczy 1 otwarty plik i jednoczesne czytanie i pisanie do niego. W tym przykładzie chodziło o zamianę 2 liter w słowie w pliku. #include <fstream> #include <iostream>
using namespace std;
int main() { fstream file("slowa.txt", ios::in | ios::out | ios::binary);
string word; while(file >> word) { size_t word_size = word.size(); if(1 < word_size) { swap(word.front(), word.back()); file.seekp(file.tellg(), ios::beg).seekp(-word_size, ios::cur); file << word; file.seekp(word_size, ios::cur); } } }
|
|
kilopierogow Temat założony przez niniejszego użytkownika |
» 2017-01-15 22:17:53 Nie do końca o to mi chodziło http://cpp0x.pl/forum/temat/?id=4391 Chcę zrobić coś podobnego do tego, tylko że na znaku a nie na wierszach. Nawet napisałem ten kod, tylko z jakiegoś głupiego powodu nie chce robić tego co powinien (zatrzymuje się na utworzeniu temp).
Plik: zxcvbbn
Użytkownik chce usunąć 4 znak. zxcbbn
Zmienia się długość pliku. Ja nie chcę zmienić znaku, ja chcę go usunąć, więc przesunąć również wszystkie znaki po wskazanym o jeden index w lewo.
Pozdrawiam. |
|
Luq |
» 2017-01-15 23:10:09 while( !plik.eof() ) { dlugosc_pliku++; }
Nie odczytałeś żadnych danych z pliku, więc eof zawsze zwróci false |
|
mokrowski |
» 2017-01-15 23:46:52 #include <fstream> #include <iostream> #include <cstdlib>
using namespace std;
int main() { fstream file("znaki.txt", ios::in | ios::out | ios::binary | ios::ate); if(file) { cerr << "Błąd otwarcia pliku.\n"; exit(EXIT_FAILURE); } char symbol; size_t count; size_t last_index = static_cast<size_t>(file.tellg()) - 1; while(true) { cout << "Podaj indeks znaku do usunięcia z zakresu [1, " << last_index << "]: "; if(not (cin >> count) or (count > last_index)) { cerr << "Podałeś nieprawidłowe dane. Próbuj jeszcze raz.\n"; cin.ignore(numeric_limits<streamsize>::max(), '\n'); continue; } break; }
file.seekp(count, ios::beg); while(file >> symbol) { file.seekp(-2, ios::cur); file << symbol; file.seekp(1, ios::cur); } // XXX: Tu sobie przytnij plik o ostatni znak. // Masz zapewne MS Windows więc zainteresuj się SetEndOfFile() aby // obciąć plik o 1 znak return EXIT_SUCCESS; }
|
|
kilopierogow Temat założony przez niniejszego użytkownika |
» 2017-01-16 00:20:30 Pokombinowałem i wyszło.
Dzięki Luq, między innymi tam był błąd w moim pierwotnym kodzie.
Dzięki mokrowski za wieloetapową pomoc.
Niech wam Bozia w pierogach wynagrodzi.
Pozdrawiam i zamykam. |
|
« 1 » |