Panel użytkownika
Nazwa użytkownika:
Hasło:
Nie masz jeszcze konta?

[C++] Usuwanie znaku z pliku

Ostatnio zmodyfikowano 2017-01-16 00:20
Autor Wiadomość
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 :
C/C++
#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.
P-156464
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ć)?
P-156466
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.
P-156467
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);
        }
    }
}
P-156469
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.
P-156474
Luq
» 2017-01-15 23:10:09
C/C++
while( !plik.eof() ) // w tym miejscu program wpada w nieskończoną pętlę
{
    dlugosc_pliku++;
}

Nie odczytałeś żadnych danych z pliku, więc eof zawsze zwróci false
P-156475
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;
}
P-156476
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.
P-156479
« 1 »
  Strona 1 z 1