Ausgabedatei kann nicht geschrieben werden



  • Hi(gh)!

    Ich habe versucht, die Map (statt meines bisherigen Ansatzes mit struct) in mein Orgelanzeigen-Reduzierprogramm zu implementieren... jetzt habe ich allerdings das Problem, dass in der Schleife, die das Quellverzeichnis nach HTML-Dateien durchgeht, im Zielordner nur die erste reduzierte HTML-Datei (mitsamt Bilddateien) angelegt wird, beim zweiten Durchlauf wird zwar noch das Unterverzeichnis (YYYYMMYY_LFDNR) angelegt, die HTML-Datei aber schon nicht mehr, das Programm bricht planmäßig ab mit der Meldung "Ziel-HTML-Datei kann nicht geöffnet werden" (Zeile 168).

    Ich kann mir darauf beim besten Willen keinen Reim drauf machen, der Zielpfad-String ist korrekt, und auch an etwaig falsch gesetzten Schreibrechten kann es nicht liegen, der Fehler tritt selbst nach chmod 777 auf!

    Hier nochmal der Code:

    /* oac (Organ Ads Compressor) 
     Programm zur Reduzierung von archivierten eBay-Elektroorgel-Anzeigen auf das zur Erfassung in Datenbanken erforderliche Minimum */
    
    // DANKSAGUNGEN:
    // Lasha Khintibidze für Hilfe beim Erzeugen von Verzeichnissen mittels create_directory (https://www.delftstack.com/de/howto/cpp/cpp-create-directory/)
    // "Finnegan" vom C++-Community-Forum für den Hinweis auf -std=c++17 als zur fehlerfreien Einbindung von <filesystem> notwendigen gcc-Compileroption
    
    #include <iostream>
    #include <fstream>
    #include <string>
    #include <vector>
    #include <dirent.h>
    #include <filesystem>
    #include <iterator>
    #include <map>
    using namespace std;
    namespace fs = std::filesystem;
    
    int main()
    {
      DIR *dir, *subdir;
      dirent *entry;
      const char *altpfad="/home/Musik/Sonstiges/WWW-Seiten, gescannte Texte/Orgeln/eBay-Kleinanzeigen/2019-01/";
      const char *neupfad="/home/Musik/Sonstiges/WWW-Seiten, gescannte Texte/Orgeln/eBay-Kleinanzeigen_neu/2019-01/";
      char *name; // Dateinamen
      ifstream datei, bilddatei;
      ofstream datei_neu;
      string source; // eingelesene Original-HTML-Textdatei als String
      string beschreibung; // Anzeigentext, zu finden nach 'itemprop="description">'
      string benutzer; // Benutzername, zu finden nach '<div class="usercard--info--collumn">'
      string ort; // Postleitzahl und Ort, zu finden nach 'itemprop="locality">'
      string erstdatum; // Erstellungsdatum, zu finden nach "Erstellungsdatum"
      string preis; // Preis, zu finden nach "Preis:"
      string filedate; // Anzeigendatum als Namens- und Titelbestandteil für zu erzeugende neue HTML-Datei
      int occ, occ2; // Variable für Stringpositionen
      char c; // eingelesenes Zeichen aus Original-HTML-Textdatei oder Datenbyte aus Bilddatei
      string dn; // Anzahl der erfassten Anzeigen eines Datums als String (Teil des Dateinamens und Titels der zu erzeugenden neuen HTML-Datei)
      string pn; // Bilddatei-Nummer als String
      /* Array, Zähler und Ergebnisvariable für Suche nach Ziffern - ich bin leider zu dumm, um die Implementation regulärer Ausdrücke in <regex> zu verstehen! */
      unsigned int pw[10]; // Array für Suchergebnisse für die Ziffern 0 bis 9
      unsigned short int i;
      unsigned int pos;
      map<string, int> Daten; // "Array" für Datums-Strings und deren Häufigkeiten
      unsigned int ad=0; // Anzeigen-Zähler
    
      dir = opendir(altpfad);
      while (dir)
      {
        entry = readdir(dir);
        if (!entry) break;
        name = entry->d_name;
      
        // cout << name << endl; // Testausgabe des Dateinamens
        string vollpfad_alt = string(altpfad);
        vollpfad_alt.append(string(name));
        if (vollpfad_alt.find("html") != -1) // nur Dateien mit Endung html öffnen!
        {
          datei.open(vollpfad_alt.c_str(), ios_base::in);
          string pfad_alt = string(altpfad);    
          // string dateiname =  "(919) Technics U50 Orgel Top Zustand in Innenstadt - Köln Altstadt | Künstler- und Musikbedarf gebraucht | eBay Kleinanzeigen.html";
          // string dateiname = "(919) Yamaha Electone HX-1 _ Orgel sehr gut erhalten! mit MDR-4 _ MIDI in Nordrhein-Westfalen - Bergisch Gladbach | Musikinstrumente und Zubehör gebraucht kaufen | eBay Kleinanzeigen.html";
          
          // datei.open("/home/Musik/Sonstiges/WWW-Seiten, gescannte Texte/Orgeln/eBay-Kleinanzeigen_neu/(919) Technics U50 Orgel Top Zustand in Innenstadt - Köln Altstadt | Künstler- und Musikbedarf gebraucht | eBay Kleinanzeigen.html", ios_base::in);
          // datei.open("/home/Musik/Sonstiges/WWW-Seiten, gescannte Texte/Orgeln/eBay-Kleinanzeigen/2019-01/Zu verschenken Orgel,alt Bontempi Master in Nordrhein-Westfalen - Borken | Zu verschenken | eBay Kleinanzeigen.html", ios_base::in);
          // datei.open (pfad_alt.append(dateiname), ios_base::in);
          if (datei)
          {
            while (datei.get(c))
            {
              source.push_back(c); // html-Datei wird eingelesen
            }
          }
          else
          {
            cerr << "Die Datei kann nicht geöffnet werden!" << endl;
          }
          
          datei.close();
          
          // Auslesen der Beschreibung
          occ = source.find("itemprop=\"description\">");
          occ2 = source.find ("</p>", occ);
          beschreibung = source.substr(occ+23, occ2-(occ+23));
    
          // Auslesen des Benutzernamens
          occ = source.find("<div class=\"usercard--info--collumn\">");
          occ = source.find("<h2>", occ);
          occ2 = source.find("</h2>", occ);
          benutzer = source.substr(occ+4, occ2-(occ+4));
             
          // Auslesen der Ortsinformationen
          occ = source.find("itemprop=\"locality\">");
          for (i=0; i<10; i++)
          {
            pw[i] = source.find((char)'0'+i, occ);
            if (i == 0)
              pos = pw[i];
            else
              if (pw[i] < pos)
                pos = pw[i];
          }
        
          occ = source.find("</span>", pos);
          ort = source.substr(pos, occ-pos);
          
          // Auslesen des Erstellungsdatums
          occ = source.find("Erstellungsdatum");
          for (i=0; i<10; i++)
          {
            pw[i] = source.find((char)'0'+i, occ);
            if (i == 0)
              pos = pw[i];
            else
              if (pw[i] < pos)
                pos = pw[i];
          }
          erstdatum = source.substr(pos, 10);
          
          
          
          // Auslesen des Preises
          occ = source.find("category: 'Zu verschenken'");
          if (occ > -1)
            preis = "0 € (zu verschenken)";
          else
          {
            occ = source.find("Preis:");
            for (i=0; i<10; i++)
            {
              pw[i] = source.find((char)'0'+i, occ);
              if (i == 0)
                pos = pw[i];
              else
                if (pw[i] < pos)
                  pos = pw[i];
            }
            occ = source.find("</h2>", pos);
            preis = source.substr(pos, occ-pos);
          }  
          filedate = erstdatum.substr(6, 4) + erstdatum.substr(3, 2) + erstdatum.substr(0, 2);
          
          if (Daten.insert(make_pair(filedate, 1)).second == false)
            Daten[filedate]++;
          
          dn = to_string(Daten[filedate]);
          if (Daten[filedate] < 10)  // Einfügung führender Nullen
            dn = "00" + dn;
          else if (Daten[filedate] < 100)
            dn = "0" + dn;
          string filedatestring;
          filedatestring = filedate + "_" + dn;  
         
          // Einrichtung des Verzeichnisses für die aktuelle neue HTML-Datei
          string dateiname_neu = filedatestring + ".html";
          string vollpfad_neu;
          vollpfad_neu = string(neupfad);
          vollpfad_neu.append(filedatestring + "/");
          fs::create_directory(vollpfad_neu);
          string vollpfad_neu2 = vollpfad_neu;
          vollpfad_neu.append(dateiname_neu);
     
         // Öffnen und Schreiben der Ausgabe-HTML-Datei
          datei_neu.open(vollpfad_neu.c_str(), ios_base::out);
          cout << "vollpfad_neu: " << vollpfad_neu << endl;
          
          if (!datei_neu)
          {
            cerr << "Ziel-HTML-Datei kann nicht geöffnet werden!" << endl;
            return 1;
          }
          else
          {
            datei_neu << "<!DOCTYPE html>\n"
                      << "<html>\n"
                      << "<head>\n"
                      << "  <meta charset=\"UTF-8\">\n"
                      << "  <title>Anzeige " << filedate << "</title>\n"
                      << "</head>\n"
                      << "<body>\n"
                      << "  <h2>Anzeige " << filedate << "</h2>\n"
                      << "  <p>\n"
                      << "    " << beschreibung << "\n"
                      << "  </p>\n"
                      << "  <table>\n"
                      << "    <tr>\n"
                      << "      <td>Benutzer:</td>\n" 
                      << "      <td>" << benutzer << "</td>\n"
                      << "    </tr>\n"
                      << "    <tr>\n"
                      << "      <td>Datum:</td>\n" 
                      << "      <td>" << erstdatum << "</td>\n"
                      << "    </tr>\n"
                      << "    <tr>\n"                  
                      << "      <td>Ort:</td>\n" 
                      << "      <td>" << ort << "</td>\n"
                      << "    </tr>\n"
                      << "    <tr>\n" 
                      << "      <td>Preis:</td>\n" 
                      << "      <td>" << preis << "</td>\n"
                      << "    </tr>\n"
                      << "  </table>\n" << endl;
                      
                      
          }   
          datei_neu.close();  
          
          
            // Auslesen und Kopieren der Bilddateien aus dem jeweiligen Datenverzeichnis der Original-HTML-Datei
          
          vollpfad_alt.erase(vollpfad_alt.find(".html"));
          vollpfad_alt.append("-Dateien/");
          cout << vollpfad_alt << endl;
          
          subdir = opendir(vollpfad_alt.c_str());
          
          i=0; // Zähler für Bilddateien
          
          string vollpfad_neu_bilddateien; // vollständiger Dateiname (mit Pfad) jeder Bilddatei
          
          while(subdir)
          {
            entry = readdir(subdir);
            if (!entry) break;
            name = entry->d_name;
            string sname = string(name);
            if (sname.find("_72") != -1) // zu kopierende Bilddateien haben das Namensschema _72*JPG
            {
              cout << sname << endl;
              i++; // Bilddateien-Zähler wird um 1 erhöht
              pn = to_string(i);
              vollpfad_neu_bilddateien = vollpfad_neu2 + filedatestring + "_Bild_" + pn + ".jpg";
              
              
              bilddatei.open(vollpfad_alt + sname, ios_base::in);
              datei_neu.open(vollpfad_neu_bilddateien, ios_base::out);
              
                    
              /* cout << "vollpfad_neu2: " << vollpfad_neu2 << endl;
              cout << "filedatestring: " << filedatestring << endl;
              cout << "\"_Bild_\" + pn + \".jpg\": " << "_Bild_" + pn + ".jpg" << endl; */
              
              if (!bilddatei)
              {
                cerr << "Quell-Bilddatei kann nicht geladen werden!" << endl;
                return -1; // Programmabbruch
              }
              else if (!datei_neu)
              {
                cerr << "Ziel-Bilddatei kann nicht geöffnet werden!" << endl;
                return -1; // Programmabbruch
              }
              else 
              {
                while (bilddatei.get(c))
                {
                  datei_neu.put(c);
                }
              }
              
              bilddatei.close();
              datei_neu.close();
            }
          }
         cout << "Anzahl der Bilddateien: " << i << endl;
         
         
         // Einbindung der kopierten Bilddateien in Code der HTML-Ausgabedatei
         datei_neu.open(vollpfad_neu, ios_base::app);
         
         cout << vollpfad_neu << endl;
         cout << vollpfad_neu2 << endl;
         cout << filedatestring << endl;
         cout << vollpfad_neu_bilddateien << endl;
         
         unsigned int j; // Zähler für Schleife
         
         string bilddateiname_rumpf = filedatestring + "_Bild_";
         
         cout << bilddateiname_rumpf << endl;
         
         for (j=1; j<=i; j++)
         {
           datei_neu << "  <p>\n"
                     << "    <img src=\"" << bilddateiname_rumpf << j << ".jpg\">\n"
                     << "  </p>\n";
         }
         
           datei_neu          << "</body>\n"
                     << "</html>" << endl;
         
         cout << "Anzeige Nr. " << ad++ << " reduziert!" << endl;            
                     
        }    
      }  
      return 0;
    }
    

    Bis bald im Khyberspace!

    Yadgar



  • Hi(gh)!

    Ich habe die Lösung gefunden: es lag daran, dass ich nach der Einbindung der kopierten Bilddateien in den HTML-Code der Ausgabedatei (ab Zeile 268) die dafür erneut geöffnete datei_neu nicht wieder geschlossen hatte!

    Danach trat aber prompt ein neues Problem auf, dessetwegen ich einen neuen Thread starten werde...

    Bis bald im Khyberspace!

    Yadgar


Anmelden zum Antworten