therap Geschrieben 25. Mai 2009 Teilen Geschrieben 25. Mai 2009 Hallo Community, ich habe folgendes Problem - und zwar möchte ich mittels fread den Inhalt einer .pdf Datei einlesen und im Puffer speichern, anschließend den Inhalt mittels fwrite in eine Datei schreiben bzw. die vorhandene ersetzen. Mein Problem ist, dass das Programm immer den selben Block kopiert bzw. ersetzt. Mein Ansatz wäre eine Schleife die mit hoch zählt oder eine Abbruch Bedingung. Ich hänge mal den Quelltext an. Vielen Dank im Voraus! #include <stdlib.h> #include <stdio.h> int main(void) { int puffer[1024]; FILE *ziel; FILE *quelle; int i; int j; ziel = fopen("ziel.txt", "w+"); quelle = fopen("quelle.txt", "r+b"); if(quelle != NULL) for (j = 0; j < 10; j++) { fread(&puffer, sizeof(int), 1024, quelle); } else { exit (1); } for(i = 0; i < 10; i++) fwrite(&quelle, sizeof(int), 1024, ziel); system("PAUSE"); return EXIT_SUCCESS; } Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen Mehr Optionen zum Teilen...
VaNaTiC Geschrieben 25. Mai 2009 Teilen Geschrieben 25. Mai 2009 Naja, das mit dem Puffern läuft im Normalfall so, dass man in einen Puffer liest, dann den Puffer schreibt und dann erst den nächsten Teil liest und wieder schreibt... Und das solange bis EOF Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen Mehr Optionen zum Teilen...
GranRoble Geschrieben 25. Mai 2009 Teilen Geschrieben 25. Mai 2009 #include <stdlib.h> #include <stdio.h> int main(void) { int puffer[1024]; FILE *ziel; FILE *quelle; int i; int j; ziel = fopen("ziel.txt", "w+"); quelle = fopen("quelle.txt", "r+b"); if(quelle != NULL) for (j = 0; j < 10; j++) { fread(&puffer, sizeof(int), 1024, quelle); fwrite(&quelle, sizeof(int), 1024, ziel); } else { exit (1); } system("PAUSE"); return EXIT_SUCCESS; } Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen Mehr Optionen zum Teilen...
TDM Geschrieben 25. Mai 2009 Teilen Geschrieben 25. Mai 2009 Ich vermisse fclose. :floet: Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen Mehr Optionen zum Teilen...
therap Geschrieben 25. Mai 2009 Autor Teilen Geschrieben 25. Mai 2009 (bearbeitet) #include <stdlib.h> #include <stdio.h> int main(void) { int puffer[1024]; FILE *ziel; FILE *quelle; int i; int j; ziel = fopen("ziel.txt", "w+"); quelle = fopen("quelle.txt", "r+b"); if(quelle != NULL) for (j = 0; j < 10; j++) { fread(&puffer, sizeof(int), 1024, quelle); fwrite(&quelle, sizeof(int), 1024, ziel); } else { fclose(ziel); fclose(quelle); exit (1); } fclose(ziel); fclose(quelle); system("PAUSE"); return EXIT_SUCCESS; } so? danke an alle vorab schonmal edit meint: nach dem ich den vorhanden code ausgeführt habe steht in der ziel datei nur kaudawelsch. teils die zeichen die ich kopiert haben möchte teils andere buchstaben etc. Bearbeitet 25. Mai 2009 von therap Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen Mehr Optionen zum Teilen...
TDM Geschrieben 25. Mai 2009 Teilen Geschrieben 25. Mai 2009 so? Nein. Wenn quelle == NULL schließt du sie im else-Block trotzdem. Außerdem wird nirgendswo abgeprüft, ob ziel geöffnet werden konnte. Des Weiteren gibts kein fflush. (Der Sauberkeit wegen) Warum eigentlich ein Integerarray? Chars wären doch angebrachter. Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen Mehr Optionen zum Teilen...
therap Geschrieben 26. Mai 2009 Autor Teilen Geschrieben 26. Mai 2009 #include <stdlib.h> #include <stdio.h> int main(void) { char puffer[100]; FILE *ziel; FILE *quelle; int j; quelle = fopen("quelle.txt", "r+b"); if (quelle == NULL) { printf("Konnte quelle.txt nicht oeffnen\n"); } ziel = fopen("ziel.txt", "w+b"); if (ziel == NULL) { printf("Konnte ziel.txt nicht oeffnen\n"); } if(quelle != NULL) for (j = 0; j < 10; j++) { fread(&puffer, sizeof(char), 1, quelle); fwrite(&quelle, sizeof(char), 1, ziel); } fclose(ziel); fclose(quelle); system("PAUSE"); return EXIT_SUCCESS; } Das Programm liest die Zeilen so weit ein, mit fflush hatte ich wenig Kontakt - konnte lediglich lesen, dass das Verhalten nicht definiert ist - Galileo Computung "C von A bis Z" Allerdings habe ich zu Blockanfang immer einen Kaudawelsch drin stehen - liegt es am fehlendem fflush? Wenn ja wo füge ich ihn ein? Hinter fread bzw. fwrite? Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen Mehr Optionen zum Teilen...
Klotzkopp Geschrieben 26. Mai 2009 Teilen Geschrieben 26. Mai 2009 Du solltest den Pufferinhalt in die Datei schreiben, nicht den FILE-Zeiger der Quelldatei. Und wenn du immer nur ein einzelnes Byte liest und schreibst, brauchst du keinen Puffer von 100 Bytes. Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen Mehr Optionen zum Teilen...
TDM Geschrieben 26. Mai 2009 Teilen Geschrieben 26. Mai 2009 Ich habs mir mal als Frühmorgensübung genommen. int main(int argc, char* argv[]) { FILE *source; FILE *destination; long lSize; char *buffer; if((source = fopen("quelle.txt", "rb")) != NULL) { fseek (source , 0 , SEEK_END); lSize = ftell (source); rewind(source); if ((destination = fopen("ziel.txt", "wb")) != NULL) { buffer = malloc(sizeof(char) * lSize); fread(buffer, sizeof(char), lSize, source); fwrite(buffer, sizeof(char), lSize, destination); fclose(source); fflush(destination); fclose(destination); free(buffer); buffer = NULL; } else { printf("Can't open %s", "ziel.txt"); fclose(source); } } else { printf("Can't open %s", "quelle.txt"); } printf("Press any key to continue."); getchar(); return EXIT_SUCCESS; } *hüstel* Wer braucht schon schleifen, ich mach das lieber gleich in einem Zug. Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen Mehr Optionen zum Teilen...
therap Geschrieben 26. Mai 2009 Autor Teilen Geschrieben 26. Mai 2009 (bearbeitet) Danke dir Klotzkopp, das Ergebnis sieht auch um Welten besser aus als zuvor. Allerdings habe ich folgendes - kontinuierliches Problem. Entweder ( ich verwende zum Testen eine .txt Datei ) - wird der Inhalt der Quelle zu oft in Ziel geschrieben oder aber die jeweils Erste Zeile von einem neuen Block ist "fehlerhaft" sprich Zeichen, die dort nicht sein sollten, bzw. gar nicht in der Datei vorhanden sind. Ich werde anbei den Inhalt von Quelle & Ziel posten. Der Quelltext ist der selbe wie der obrige. Edit sieht: Habe gerade den Post von TDM gesehen - danke dafür! Danke auch den anderen. Kann mir nur jmd. sagen wofür fseek zuständig ist? Ich würde sagen, dass ich innerhalb der Datei umherspringe.. Bzw. ftell, rewind sagt mir ebenfalls gar nichts :x *schnell gidf.de öffne* Bearbeitet 26. Mai 2009 von therap Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen Mehr Optionen zum Teilen...
TDM Geschrieben 26. Mai 2009 Teilen Geschrieben 26. Mai 2009 Kann mir nur jmd. sagen wofür fseek zuständig ist? Ich würde sagen, dass ich innerhalb der Datei umherspringe.. Bzw. ftell, rewind sagt mir ebenfalls gar nichts :x *schnell gidf.de öffne* fseek - C++ Reference ftell - C++ Reference rewind - C++ Reference Oder grob: fseek setzt den "Cursor" in der Datei. ftell gibt diese Position zurück. rewind setzt ihn wieder auf den Anfang. Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen Mehr Optionen zum Teilen...
therap Geschrieben 26. Mai 2009 Autor Teilen Geschrieben 26. Mai 2009 Danke nochmals für die Hilfe. Ich habe noch ein ungewolltes Problem, welches in einem Teilbereich auftritt. Und zwar möchte ich aus einer .csv Datei eine Zeile auslesen. Diese anhand von ";" splitten und in 3 Variablen sichern. Pfad, Dateiname & Aktion ( aktion wird ausgewertet um zu entscheiden ob die Datei kopiert bzw. gelöscht werden soll ) Das ganze funktioniert wunderbar.. mit der ersten Zeile. Die 2. Zeile wird zwar eingelesen. Aber nicht richtig ausgeführt. Anbei die Schleifen, welche den String splitten sowie die Funktion die den String zusammen setzt. // MAX = 200 while(fgets(gesamte_zeile, MAX, file_csv)) { fputs(gesamte_zeile, file_csv); ptr_strtok = strtok(gesamte_zeile, ";\n"); while(ptr_strtok != NULL) { i++; switch (i) { case 1: strcpy(pfad, ptr_strtok); break; case 2: strcpy(dateiname, ptr_strtok); break; case 3: aktion = atoi(ptr_strtok); i = 0; break; default: sprintf(sMsg, "Unbekannter Operator", CSV); printlog(sMsg); } ptr_strtok = strtok (NULL, ";\n"); } fc_dateipfad(pfad, dateiname, dateipfad); char fc_dateipfad ( char *pfad, char *dateiname, char *dateipfad ) { // Add dateiname at dateipfad strcpy(dateipfad, pfad); strcat(dateipfad, dateiname); return *dateipfad; } Danke im Voraus. Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen Mehr Optionen zum Teilen...
TDM Geschrieben 26. Mai 2009 Teilen Geschrieben 26. Mai 2009 Gehe ich recht in der Annahme, dass es mit diesem Thread zusammenhängt? Poste dort am Besten mal den kompletten (neuen?) Quelltext. Mit "Stückchenhinwerfen" kann ich nix anfangen. :floet: Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen Mehr Optionen zum Teilen...
Klotzkopp Geschrieben 26. Mai 2009 Teilen Geschrieben 26. Mai 2009 Die 2. Zeile wird zwar eingelesen. Aber nicht richtig ausgeführt. Wenn das Einlesen funktioniert (das hast du hoffentlich mit dem Debugger geprüft), das Ausühren aber nicht, warum zeigst du dann den Code für's Einlesen, und nicht den für's Ausführen? Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen Mehr Optionen zum Teilen...
therap Geschrieben 26. Mai 2009 Autor Teilen Geschrieben 26. Mai 2009 (bearbeitet) @ Klotzkopp - ja ich habe das im Debugger von Dev-C++ geprüft. Schritt für Schritt. Anbei der gesamte Quelltext. #include <stdio.h> #include <stdlib.h> #include <string.h> #include <time.h> #define MAX 200 #define BLOCK 1024 #define CSV "Steuerdatei.csv" #define TOKEN_LENGTH 100 void printlog ( char *s ); void fc_aktion(char *dateipfad, char *dateiname,int aktion, char *puffer,char *sMsg); char fc_dateipfad ( char *pfad, char *dateiname, char *dateipfad ); int main(int argc, char *argv[]) { FILE *file_csv; char pfad[TOKEN_LENGTH], dateipfad[MAX], dateiname[TOKEN_LENGTH], gesamte_zeile[MAX], sMsg[BLOCK], *ptr_strtok, c; int aktion, i = 0; printlog("Log-File.txt wurde erstellt:"); // Open .csv File file_csv = fopen(CSV, "r"); // Troubleshooting .csv File if (NULL == CSV) { sprintf(sMsg, "'%s' Konnte nicht geoeffnet werden", CSV); printlog(sMsg); return 1; } // Open .csv File successful sprintf(sMsg, "'%s' wurde erfolgreich geoeffnet", CSV); printlog(sMsg); // Read line by line from .csv File while(fgets(gesamte_zeile, MAX, file_csv)) { fputs(gesamte_zeile, file_csv); ptr_strtok = strtok(gesamte_zeile, ";\n"); while(ptr_strtok != NULL) { i++; switch (i) { case 1: strcpy(pfad, ptr_strtok); break; case 2: strcpy(dateiname, ptr_strtok); break; case 3: aktion = atoi(ptr_strtok); i = 0; break; default: sprintf(sMsg, "Unbekannter Operator", CSV); printlog(sMsg); } ptr_strtok = strtok (NULL, ";\n"); } fc_dateipfad(pfad, dateiname, dateipfad); fc_aktion(dateipfad, dateiname, aktion, puffer, sMsg); } // Close Streams fclose(file_csv); printf("\nAktualisierung erfolgreich - Einzelheiten entnehmen Sie dem Log-File.txt\n\n"); system("PAUSE"); return 0; } // Generate dateipfad char fc_dateipfad ( char *pfad, char *dateiname, char *dateipfad ) { // Add dateiname at dateipfad strcpy(dateipfad, pfad); strcat(dateipfad, dateiname); return *dateipfad; } // Action void fc_aktion(char *dateipfad, char *dateiname,int aktion, char *puffer,char *sMsg) { // Action with Operator FILE *file_to, *file_from; char *buffer; long lSize; switch (aktion) { // Delete File case 1 : remove(dateipfad); sprintf(sMsg, "'%s' wurde geloescht", dateiname); printlog(sMsg); break; // Replace File case 2: { if((file_from = fopen(dateiname, "rb")) != NULL) { fseek (file_from , 0 , SEEK_END); lSize = ftell (file_from); rewind(file_from); if ((file_to = fopen(dateipfad, "wb")) != NULL) { buffer = malloc(sizeof(char) * lSize); fread(buffer, sizeof(char), lSize, file_from); fwrite(buffer, sizeof(char), lSize, file_to); fclose(file_from); fflush(file_to); fclose(file_to); free(buffer); buffer = NULL; } else { printf("Kann %s nicht oeffnen", dateiname); fclose(file_from); } } else { printf("Kann %s nicht oeffnen", dateiname); } sprintf(sMsg, "'%s' wurde ersetzt", dateiname); printlog(sMsg); } break; default: sprintf(sMsg, "'%s' Ungueltiger Operator", aktion); printlog(sMsg); } } void printlog ( char *s ) { FILE *log_file; struct tm *local; time_t t; t = time(NULL); local = localtime(&t); log_file = fopen("Log-File.txt", "w+"); if(log_file != NULL) { fprintf(log_file, "[%s] %s\n", asctime(local), s); fclose(log_file); } } Kann gut sein, das noch irgendwelche Variablen deklariert aber nicht verwendet werden. Dessen bin ich mir im Klaren - die werden natürlich nachträglich entfernt. Das ist der Momentane Stand. Bearbeitet 26. Mai 2009 von therap Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen Mehr Optionen zum Teilen...
TDM Geschrieben 26. Mai 2009 Teilen Geschrieben 26. Mai 2009 Wie definierst du "nicht richtig"? Was ist erwartet? Was wird gemacht? Ich vermute mal, dass es mit unsauberer Variablenbelegung zu tun hat. (Irgendwelche Werte der vorherigen Zeile etc.) [Offtopic] - Soviel zu "dort". (Nächstes Mal mach ichs lieber bunt. ) - Igitt, Dev-C++ [/Offtopic] Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen Mehr Optionen zum Teilen...
therap Geschrieben 26. Mai 2009 Autor Teilen Geschrieben 26. Mai 2009 Offtopic: Ich würde auch gerne lieber in einer anderen Umgebung arbeiten - leider wurde es mir so vorgeschrieben. Und dem habe ich mich zu fügen als Azubi. Back2Topic: Entschuldige, ich hätte mich präzieser ausdrücken müssen. Also, erwartet wird - dass, jeweils eine Zeile aus der Steuerdatei.csv gelesen wird - diese in "gesamte_zeile" gesichert wird. Anschließend mittels strtok in Tokens geteilt ( anhand von ";" ) Diese Tokens ( 3 in der Zahl ) in eine jeweils andere Variable speichert. Pfad, Dateiname, Aktion Anschließend soll mittels strcpy der Token Pfad in die Variable Dateipfad gespeichert werden bzw. kopiert. Anschließend mittels strcat soll der Dateiname an den Pfad in Var. Dateipfad angehängt werden. Danach soll anhand der Var. Aktion geprüft werden, was zu tun ist sprich: löschen o. ersetzen / kopieren. Was wird gemacht: Die Zeile aus .csv gelesen - in gesamte_zeile gespeichert 3 Tokens werden in jeweils 1 Var. gespeichert ( anhand von ";" ) Dateiname wird an Pfad gehängt ( mittels strcat ) Operator wird geprüft, und ausgeführt - dies allerdings nur mit der ersten Zeile in .csv Alle nachfolgenden Zeilen werden zwar korrekt eingelesen und in gesamte_zeile gespeichert - diese werden auch korrekt geteilt anhand von ";" - allerdings passiert nichts. Wobei... da fällt mir etwas auf - und zwar habe ich 3 Zeilen in meiner .csv Datei - das Programm bzw. die While Schleife springt allerdings nach der 2. Zeile komplett raus und beendet sich. Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen Mehr Optionen zum Teilen...
TDM Geschrieben 26. Mai 2009 Teilen Geschrieben 26. Mai 2009 (bearbeitet) Wenn du mit fgets(gesamte_zeile, MAX, file_csv) arbeitest, liest du nicht die komplette Zeile ein, sondern 200 (MAX) Zeichen. Das kann mehr, aber auch weniger als die Zeile sein. Daraus ergeben sich dann natürlich Folgefehler durch dein switch(i)-i++-i=0-Konstrukt. [Editerle] Ich seh grad, dass fgets wohl doch an Zeilenumbrüchen aufhört. Ich hätte hier zwar eher mit fscanf und feof gearbeitet, aber naja... Hast du denn durchgebuggt, dass jede Zeile sicher den zu erwartenden Wert besitzt? Bearbeitet 26. Mai 2009 von TDM Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen Mehr Optionen zum Teilen...
therap Geschrieben 26. Mai 2009 Autor Teilen Geschrieben 26. Mai 2009 Und wie könnte ich es umgestalten damit ich diesen Folgefehler umgehen kann? Tut mir wirklich leid, das ich teilweise so bescheidene Fragen stelle - aber wenn man keinen Ansprechpartner hat ist nicht alles trivial bzw. einfach. Deswegen nochmal großes Dankeschön an euch Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen Mehr Optionen zum Teilen...
Klotzkopp Geschrieben 26. Mai 2009 Teilen Geschrieben 26. Mai 2009 while(fgets(gesamte_zeile, MAX, file_csv)) { fputs(gesamte_zeile, file_csv);Warum schreibst du die gerade ausgelesene Zeile wieder in die Datei hinein? Was soll das fputs da? Und warum gibt fc_dateipfad das erste Zeichen des zusammengesetzen Pfades zurück, aber beim Aufruf wird mit dem Rückgabewert gar nichts gemacht? Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen Mehr Optionen zum Teilen...
TDM Geschrieben 26. Mai 2009 Teilen Geschrieben 26. Mai 2009 Und wie könnte ich es umgestalten damit ich diesen Folgefehler umgehen kann? Zumal das fputs rausnehmen, wie Klotzkopp schon anmerkte. Ich hab da mal ein bisschen rumgespielt, muss sicher noch angepasst werden, aber funktioniert soweit, dass jede Zeile korrekt ausgelesen wird und die Daten zur Verfügung stehen. Musst mal sehen, ob du damit was anfangen kannst: int readLine(FILE *stream, int max, char* line); void splitLine(char *line, char *path, char *fileName, int *action); int main(int argc, char* argv[]) { char path[200], fileName[200]; char *line = malloc(sizeof(char) * 1024); int action; FILE *stream; // Read line by line from .csv File if ((stream = fopen("test.csv", "r")) != NULL) { while(readLine(stream, 200, line)) { splitLine(line, path, fileName, &action); //Ab hier weitere Verarbeitung der Werte } } free(line); line = NULL; return 0; } int readLine(FILE *stream, int max, char* line) { char *buffer; if(ferror(stream) || feof(stream)) return 0; buffer = fgets(line, max, stream); return ((strcmp(buffer, line) == 0) && (line != NULL)); } void splitLine(char *line, char *path, char *fileName, int *action) { //Default strcpy(path, ""); strcpy(fileName, ""); (*action) = -1; //Default const char *delims = ";"; char *buffer = strtok(line, delims); int i; for(i = 0; (i < 3) && (buffer != NULL); i++, buffer = strtok(NULL, delims)) { switch (i) { case 0: strcpy(path, buffer); break; case 1: strcpy(fileName, buffer); break; case 2: (*action) = atoi(buffer); break; default: printf("Fehler in Zeile: %s", line); break; } } } Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen Mehr Optionen zum Teilen...
therap Geschrieben 27. Mai 2009 Autor Teilen Geschrieben 27. Mai 2009 Danke euch allen. Ich hatte auch die Zeile mit fputs rausgenommen, sicher muss der Code noch optimiert werden - aber er erfüllt z.Z. seinen Zweck Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen Mehr Optionen zum Teilen...
Empfohlene Beiträge
Dein Kommentar
Du kannst jetzt schreiben und Dich später registrieren. Wenn Du ein Konto hast, melde Dich jetzt an, um unter Deinem Benutzernamen zu schreiben.