Doppelte Strings aus einer Datei löschen

  • geschlossen
  • C

Diese Seite verwendet Cookies. Durch die Nutzung unserer Seite erklären Sie sich damit einverstanden, dass wir Cookies setzen. Weitere Informationen

  • Doppelte Strings aus einer Datei löschen

    Hier die Funktion, ich komm einfach nicht weiter.
    Alles wurde einwandfrei übergeben, nur beim lesen und schreiben in die neue Datei happert es.
    Ich bitte um Hilfe und wenn möglich, reines C, weil C++ versteh ich noch nicht.

    PHP-Quellcode

    1. void dupeex(char *eingabe1,char *eingabe2) {
    2. FILE *fp1=NULL;
    3. FILE *fp2=NULL; //File Pointer fuer dupe-beinhaltete Datei und fuer Ausgabedatei
    4. long spi1=0;
    5. long spi2=0;
    6. char buf1[4097];
    7. char buf2[4097];
    8. int i=0;
    9. fp1=fopen(eingabe1, "rt");
    10. fp2=fopen(eingabe2, "a+t");
    11. spi1=ftell(fp1);
    12. spi2=ftell(fp2);
    13. rewind(fp1);
    14. rewind(fp2);
    15. puts(eingabe1);
    16. puts(eingabe2);
    17. getch();
    18. while(fgets(buf1,sizeof(buf1),fp1)) {
    19. while(fgets(buf2,sizeof(buf2),fp2)) {
    20. if(!strcmp(buf1,buf2))
    21. {
    22. printf("%s");
    23. getch();
    24. fputs(buf1,fp2);
    25. }
    26. }
    27. }
    28. fseek(fp1,spi1,SEEK_SET);
    29. fseek(fp2,spi2,SEEK_SET);
    30. fclose(fp1);
    31. fclose(fp2);
    32. }
    Alles anzeigen
  • Ist zwar etwas spät, aber ich war ne Weile offline. Und ich kann dir jetzt auf die Schnelle auch keine fertige Lösung stricken.

    Zunächst mal der Kleinkram: das Programm enthält mehrere Unschönheiten. Beispielsweise machst du keinerlei Fehlerprüfung. Du merkst gar nicht, wenn das Öffnen der Dateien nicht klappt. Und siehst folglich auch nicht den Grund dafür. Also
    if (fp1 == NULL) perror("Open-Fehler fuer Datei 1:");
    sollte hinter jedem Open stehen (analog für fp2).

    Damit das Programm überhaupt funktioniert, darf auch eingabe1 nicht identisch sein mit eingabe2.

    Du benutzt strcmp als zum Vergleichen. Diese Funktion sagt "gleich", wenn alle Zeichen in den untersuchten Strings übereinstimmen. Genaugenommen liefert sie den Wert 0, wenn die untersuchten Strings übereinstimmen (also false). Das musst du in deinen Bedingungen bedenken. Der if-Block im while wird also ausgeführt, wenn die Zeilen identisch sind. Vermutlich willst du das eher umgekehrt.

    Und den String liest du mit fgets ein. Diese Funktion liest eine komplette Zeile ein, sofern sie nicht größer als dein Puffer ist (4096 Bytes).

    In der Summe heisst das: du suchst in den Dateien nach Zeilen mit komplett identischem Inhalt. Ich nehme mal an, dass es das ist, was du auch willst.

    Und der letzte ganz große Fehler betrifft das ganze Schreiben in die Datei: das funktioniert so nicht.

    Du liest eine Zeile aus Datei1, und liest dann alle Zeilen aus Datei2 und vergleichst. Nachdem die innere While-Schleife (für fp2) einmal durchlaufen ist, steht der Dateipointer am Ende der Datei. Im nächsten Durchlauf der äußeren Schleife liest du nun die zweite Zeile aus Datei1 und möchtest jetzt wieder jede Zeile aus Datei2 haben, um sie zu vergleichen. Da du aber immer noch am Ende der Datei2 stehst, bekommst du nix mehr. Du musst also nach jedem Durchlauf der inneren Schleife die Datei2 zurück an den Anfang positionieren (rewind).
    Weiter müsstes du bei deinem Lösungsansatz zwei Zähler mitführen und ständig aktuell halten (nach jedem(!) Lese- und Schreibvorgang in der Zieldatei), um vor jedem Schreiben auf die richtige Schreibposition zu stellen (mit fseek) und danach wieder auf die entsprechende Leseposition.

    Das Ganze wird deutlich einfacher, wenn du eine dritte Datei als Ergebnisdatei verwendest und diese (falls nötig) am Ende über die zweite Datei drüber move'st. Das spart dir die Positionsmerker.

    Die meisten deiner Fehler deuten darauf hin, dass du vorher keinen sauberen Plan gemacht und den trocken an einem kleinen Beispiel ausgetestet hast. Das führt dazu, dass du während der Programmierung nicht nur mit den Befehlen kämpfst, sondern auch noch mit der Planung beschäftigt bist. Das macht dir die Arbeit unnötigt kompliziert, solange du noch nicht eine gewisse Sicherheit erreicht hast. Selbst Probleme, die sich so einfach anhören wie "Eleminiere doppelte Zeilen aus einer Datei" können in der Programmierung überraschend kompliziert sein. Daher hilft es enorm, die Arbeitsschritte "Planung" und "Umsetzung" zu trennen. Das sieht zwar immer so aus, als würde das einfach nur mehr Arbeit kosten, aber überleg mal, wieviel Zeit du in die Fehlersuche gesteckt hast.

    Grüße
    Michael
  • Vielen Dank für die große Hilfe und deine ehrliche Meinung!
    Ich werde wohl meine Programmierkenntnise überarbeiten müssen und lernen zu planen.

    Ich werde daran arbeiten und hoffe es wird mir gelingen.