PNG Datein funktionieren nicht mehr nach dem entpacken

Ninjasturm

Mitglied
Hallo tutorials.de,

ich habe mir einen FileArchiver und einen FileExtractor programmiert. Bei normalen Textdatein funktionieren beide super. Nur wenn ich jetzt versuche PNG Datein zu packen und wieder zu entpacken funktionieren diese nicht mehr.
Die gepackte Datei ist etwa so aufgebaut:
C:\Datei1.txt
(%?{?%)
Hallo1
(%?}?%)
C:\Datei2.txt
(%?{?%)
Hallo2
(%?}?%)

Zum packen und entpacken benutze ich fstream und mein Compiler ist MinGW.

Vielen Dank im Voraus.
 
1. Code:
Extractor:
C++:
#include <cstdlib>
#include <fstream>
#include <iostream>
#include <string>
using namespace std;

int main(int numberofArgs, char* pszArgs[])
{
    // für jede übergebene Datei ausführen
    cout << "Extractor" << endl;
    cout << "-----------------------"<< endl;
    string source;
    cout << "Source: "; cin >> source;
    cout << "-----------------------"<< endl;
    ifstream input(source.c_str(),
            ios_base::in|ios_base::binary);
    while (!input.eof())
    {
        string Buffer;
        input >> Buffer;
        ofstream Output(Buffer.c_str(), ios::trunc|ios_base::binary);
        input >> Buffer;
        if (Buffer == "(%?{?%)")
        {
            // Datei beginnt
            while (Buffer != "(%?}?%)")
            {
                input >> Buffer;
                if (Buffer != "(%?}?%)")
                {
                    Output << " ";
                    Output << Buffer;
                }
                else
                {
                    break;
                }
            }
        }
    }
    system("PAUSE");
    return 0;
}
Archiver:
C++:
#include <cstdlib>
#include <fstream>
#include <iostream>
#include <string>
using namespace std;

int main(int numberofArgs, char* pszArgs[])
{
    // für jede übergebene Datei ausführen
    cout << "Archiver" << endl;
    cout << "-----------------------"<< endl;
    string target;
    cout << "Target: "; cin >> target;
    cout << "-----------------------"<< endl;
    cout << "Clear target(Yes/No)?";
     string ClearYesNo;
    cin >> ClearYesNo;
    cout << "-----------------------"<< endl;
    if (ClearYesNo == "Yes" || ClearYesNo == "yes")
    {
        cout << "Clearing " << target;
        ofstream Clear(target.c_str(),
        ios_base::out|ios_base::trunc|ios_base::binary);
        Clear << "";
        cout << " done" << endl;
        cout << "-----------------------"<< endl;
    }
    for (int n = 1; n < numberofArgs; n++)
    {
        // Dateinamen erzeugen mit einem Anhängsel
		string source = pszArgs[n];

        // jetzt die Quelle öffnen zum lesen,
		// das Ziel zum schreiben
		ifstream input(source.c_str(),
                       ios_base::in|ios_base::binary);

		ofstream output(target.c_str(),
          ios_base::out| ios_base::app);
        if (input.good() && output.good())
        {
            cout << "Packing " << source << " to " << target;
            output << source << "\n(%?{?%)\n";
            while(!input.eof() && input.good())
            {
                char buffer[4096];
                input.read(buffer, 4096);
                output.write(buffer, input.gcount());
            }
            output << "\n(%?}?%)\n";
            cout << " done" << endl;
        }
        else
        {
            cerr << "Packing " << source << " failed" << endl;
        }
    }

    system("PAUSE");
    return 0;
}
2. Ja ich benutze ios::binary, ist doch dann Binär?
 
Zuletzt bearbeitet von einem Moderator:
Hi.

1) Kardinalfehler: du verwendest eof. Wenn du nicht genau weißt wie eof, bad, good und fail funktionieren laß die Finger davon - abgesehen davon das das Verhalten von eof() nicht genau definiert ist.

2) du verwendest formatierte Eingabeoperationen -- operator>> überspringt Leerzeichen, außer du hast noskipws aktiviert.

3) du schreibst da willkürlich Leerzeichen in die Ausgabe, obwohl du gar nicht weißt welches Freizeichen (\n \r \t ' ') bzw. wieviele gelesen wurden.

4) Und um eine Zeile einzulesen, solltest du std::getline verwenden (sonst ist dort ein \n Zeichen zuviel drin).

Archivieren:
C++:
const string delim = "(%?{?%)";

ofstream output(target.c_str(), ios::out | ios::binary);

if (!output.is_open()) {
  cerr << "Ausgabefehler: " << target << endl;
  exit(1);
}

for (...) {
  ifstream input(source.c_str(), ios::in | ios::binary);

  if (!input.is_open()) {
    cerr << "fehler: " << input;
    continue;
  }

  if (!(output << source << '\n'
         << delim << '\n'
         << input.rdbuf()  // schreibe Daten von input auf output
         << '\n' << delim << '\n'))
  {
    cerr << "ausgabefehler: " << target << endl;
    exit(3);
  }
}
Um die Daten zu Extrahieren könntest du ähnlich vorgehen und getline() verwenden um die Trennzeilen zu finden.

Gruß
 
Zuletzt bearbeitet:
Ich hab jetzt meine Code geändert allerdings bringt er mir dann immer die Meldung, dass das Archiv nicht gepackt werden konnte. Also der Fehler passiert beim schreiben in die Datei.
Kannst du mri vielleicht auch mal erklären was die Funktion rdbuf genau macht?
Schreibt rdbuf alles was in input steht auf output oder wie muss ich das verstehen.
C++:
#include <cstdlib>
#include <fstream>
#include <iostream>
#include <string>
using namespace std;

int main(int numberofArgs, char* pszArgs[])
{
    cout << "Archiver" << endl;
    cout << "-----------------------"<< endl;
    string target;
    cout << "Target: "; cin >> target;
    cout << "-----------------------"<< endl;
    cout << "Clear target(Yes/No)?";
     string ClearYesNo;
    cin >> ClearYesNo;
    cout << "-----------------------"<< endl;
    if (ClearYesNo == "Yes" || ClearYesNo == "yes")
    {
        cout << "Clearing " << target;
        ofstream Clear(target.c_str(),
        ios_base::out|ios_base::trunc|ios_base::binary);
        Clear << "";
        cout << " done" << endl;
        cout << "-----------------------"<< endl;
    }
    std::string begin = "(%?{?%)";
    std::string delim = "(%?}?%)";
    ofstream output(target.c_str(), ios::out | ios::binary| ios::app);

    if (!output.is_open())
     {
        cerr << "Ausgabefehler: " << target << endl;
        numberofArgs = 0;
    }
    for (int n = 1; n < numberofArgs; n++)
    {
		string source = pszArgs[n];

		ifstream input(source.c_str(),
                       ios_base::in|ios_base::binary);

        if (!input.is_open())
        {
            cerr << "Failed to open: " << input;
            continue;
        }
        if (!(output << source << '\n'
            << begin << '\n'
            << input.rdbuf()  // schreibe Daten von input auf output
            << delim << '\n'))
              {
                    cerr << "Error while packing: " << target << endl;
                    break;
            }
    }

    system("PAUSE");
    return 0;
}
 
Zuletzt bearbeitet von einem Moderator:
Ich hab jetzt meine Code geändert allerdings bringt er mir dann immer die Meldung, dass das Archiv nicht gepackt werden konnte. Also der Fehler passiert beim schreiben in die Datei.
Dein Programm funktioniert bei mir tadellos. Bist du sicher, du führst das richtige Programm aus?
Kannst du mri vielleicht auch mal erklären was die Funktion rdbuf genau macht?
Schreibt rdbuf alles was in input steht auf output oder wie muss ich das verstehen.
rdbuf() ruft das aktuelle filebuf Objekt des Streams ab. operator<<(streambuf*) kopiert die Daten direkt von diesem Puffer in die Ausgabe.

Gruß

PS: Du hast ein Semikolon zuviel nach dem if.
 
Zuletzt bearbeitet:
Vielen Dank das mit dem Archivieren funktioniert jetzt ja schon allerdings weis ich net wie ich des entpacken soll da er ja immer nur einen bestimmten Teil auslesen muss. Wie könnte ich des mit dem entpacken lösen.

P.S.: Ich hab nicht viel Ahnung von fstream.
 
Hi.

Bsp:
C++:
    string target, line;

    while (getline(input, target) &&
           getline(input, line) &&
           line == delim &&
           getline(input, line))
    {
        clog << "name: " << target << endl;

        ofstream output(target.c_str(), ios::out | ios::binary);

        if (!output.is_open()) {
            cerr << "ausgabefehler: " << target << endl;
        } else if (line != delim) {
            while (output << line) {
                if (!getline(input, line)) {
                    cerr << "lesefehler: " << source << endl;
                    exit(5);
                } else if (line != delim) {
                    output << '\n';
                } else break;
            }
            if (!output) {
                cerr << "ausgabefehler" << endl;
            }
        }
    }
    if (input.bad() || !input.eof()) {
        cerr << "lesefehler: " << source << endl;
    }
Gruß
 

Neue Beiträge

Zurück