Zum Inhalt springen

ANSI C, fread & fwrite


therap

Empfohlene Beiträge

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;

}

Link zu diesem Kommentar
Auf anderen Seiten teilen

#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;

}

Link zu diesem Kommentar
Auf anderen Seiten teilen

#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 von therap
Link zu diesem Kommentar
Auf anderen Seiten teilen

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.

Link zu diesem Kommentar
Auf anderen Seiten teilen


#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?

Link zu diesem Kommentar
Auf anderen Seiten teilen

Ich habs mir mal als Frühmorgensübung genommen. :D


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.

Link zu diesem Kommentar
Auf anderen Seiten teilen

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 von therap
Link zu diesem Kommentar
Auf anderen Seiten teilen

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.

Link zu diesem Kommentar
Auf anderen Seiten teilen

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.

Link zu diesem Kommentar
Auf anderen Seiten teilen

@ 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 von therap
Link zu diesem Kommentar
Auf anderen Seiten teilen

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. :rolleyes:)

- Igitt, Dev-C++

[/Offtopic]

Link zu diesem Kommentar
Auf anderen Seiten teilen

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.

Link zu diesem Kommentar
Auf anderen Seiten teilen

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 von TDM
Link zu diesem Kommentar
Auf anderen Seiten teilen

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 :)

Link zu diesem Kommentar
Auf anderen Seiten teilen

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?

Link zu diesem Kommentar
Auf anderen Seiten teilen

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;

		}

	}

}

Link zu diesem Kommentar
Auf anderen Seiten teilen

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.

Gast
Auf dieses Thema antworten...

×   Du hast formatierten Text eingefügt.   Formatierung wiederherstellen

  Nur 75 Emojis sind erlaubt.

×   Dein Link wurde automatisch eingebettet.   Einbetten rückgängig machen und als Link darstellen

×   Dein vorheriger Inhalt wurde wiederhergestellt.   Editor leeren

×   Du kannst Bilder nicht direkt einfügen. Lade Bilder hoch oder lade sie von einer URL.

Fachinformatiker.de, 2024 by SE Internet Services

fidelogo_small.png

Schicke uns eine Nachricht!

Fachinformatiker.de ist die größte IT-Community
rund um Ausbildung, Job, Weiterbildung für IT-Fachkräfte.

Fachinformatiker.de App

Download on the App Store
Get it on Google Play

Kontakt

Hier werben?
Oder sende eine E-Mail an

Social media u. feeds

Jobboard für Fachinformatiker und IT-Fachkräfte

×
×
  • Neu erstellen...