DAtei öffnen --- auslesen
-
gar nicht, weil ich nicht weiß WO ich das einsetzen soll und WIE und weil ich echt dumm bin
was für ne kacke ... is doch net wahr
-
Gut, erstmal zu deinem bestehenden Code.
Troja2k schrieb:
case 1: printf("********** Airplus **********\n"); int numclosed; char line[100]; /* Open for read (will fail if file "Air_Plus_Beispiel.xls" does not exist) */ if( (stream = fopen( "Air_Plus_Beispiel.csv", "r" )) != NULL ) { printf( "The file 'Air_Plus_Beispiel.csv' was opened\n" ); if( fgets( line, 100, stream ) == NULL) printf( "fgets error\n" ); else printf( "%s", line); fclose( stream ); } else printf( "The file 'cAir_Plus_Beispiel.csv' was not opened\n" ); /* Open for write */ if( (stream2 = fopen( "test.csv", "w+" )) == NULL ) printf( "The file 'test.csv' was not opened\n" ); else printf( "The file 'test.csv' was opened\n" ); /* Close stream */ if( fclose( stream ) ) printf( "The file 'Air_Plus_Beispiel.csv' was not closed\n" ); /* All other files are closed: */ numclosed = _fcloseall( ); printf( "Number of files closed by _fcloseall: %u\n", numclosed ); break;
Hier solltest du erstmal das Öffnen der zweiten Datei vor dem Einlesen der ersten machen. Das Schließen natürlich danach ;).
Dann kommen wir zum Einlesen selbst. Bisher liest du nur eine Zeile aus. Hier wärs angebraucht erstmal eine Schleife einzubauen. Diese soll solange laufen, solange etwas von der Datei gelesen werden kann. Schau dir dazu mal den Rückgabewert von fgets() an.
Versuche vorerst nur das eingelesene in der Schleife am Bildschirm auszugeben. Der Inhalt der Datei sollte dann also komplett am Bildschirm stehen. Wenn du so weit bist, machen wir weiter :).
-
#include <stdio.h> //für printf #include <conio.h> //für getch(); #include <process.h> //für fprintf // crt_fopen.c /* This program opens two files. It uses * fclose to close the first file and * _fcloseall to close all remaining files. */ #include <stdio.h> FILE *stream, *stream2; main() { char cDateiAuswahl; int numclosed; char line[100]; printf("********** Datei-Auswahl **********\n\n"); printf("1. Airplus\n"); printf("2. Vodafone\n"); printf("3. Beenden\n\n"); printf("Bitte waehlen Sie nun, welche Datei sie verarbeiten wollen.\n\n"); printf("Ihre Eingabe: "); scanf("%i",&cDateiAuswahl); printf("\n\n\n"); switch(cDateiAuswahl) { case 1: printf("********** Airplus **********\n"); /* Open for read (will fail if file "Air_Plus_Beispiel.xls" does not exist) */ if( (stream = fopen( "Air_Plus_Beispiel.csv", "r" )) != NULL ) { printf( "The file 'Air_Plus_Beispiel.csv' was opened\n" ); //open for write if( (stream2 = fopen( "test.csv", "w+" )) == NULL ) printf( "The file 'test.csv' was not opened\n" ); else printf( "The file 'test.csv' was opened\n" ); //read line if( fgets( line, 200, stream ) == NULL) printf( "fgets error\n" ); else printf( "%s", line); fclose( stream ); } else printf( "The file 'cAir_Plus_Beispiel.csv' was not opened\n" ); /* Close stream */ if( fclose( stream ) ) printf( "The file 'Air_Plus_Beispiel.csv' was not closed\n" ); /* All other files are closed: */ numclosed = _fcloseall( ); printf( "Number of files closed by _fcloseall: %u\n", numclosed ); break; case 2: printf("********** Vodafone **********\n"); break; case 3: printf("********** Programm wird beendet **********\n"); break; default : printf("********** Falsche Eingabe! **********\n"); break; } system("pause"); }
so, nun hab ich erstmal alles korrekt umgestellt und es läuft auch noch
Hier wärs angebraucht erstmal eine Schleife einzubauen. Diese soll solange laufen, solange etwas von der Datei gelesen werden kann. Schau dir dazu mal den Rückgabewert von fgets() an.
also eine while - do schleifen, richtig? aber wo tu ich die rein? vorm einlesen? wie meinst du das mit rückgabewert von fgets?
-
#include <stdio.h> //für printf #include <conio.h> //für getch(); #include <process.h> //für fprintf // crt_fopen.c /* This program opens two files. It uses * fclose to close the first file and * _fcloseall to close all remaining files. */ #include <stdio.h> FILE *stream, *stream2; main() { char cDateiAuswahl; int numclosed; char line[100]; printf("********** Datei-Auswahl **********\n\n"); printf("1. Airplus\n"); printf("2. Vodafone\n"); printf("3. Beenden\n\n"); printf("Bitte waehlen Sie nun, welche Datei sie verarbeiten wollen.\n\n"); printf("Ihre Eingabe: "); scanf("%i",&cDateiAuswahl); printf("\n\n\n"); switch(cDateiAuswahl) { case 1: printf("********** Airplus **********\n"); /* Open for read (will fail if file "Air_Plus_Beispiel.xls" does not exist) */ if( (stream = fopen( "Air_Plus_Beispiel.csv", "r" )) != NULL ) { printf( "\nThe file 'Air_Plus_Beispiel.csv' was opened\n" ); //open for write if( (stream2 = fopen( "test.csv", "w+" )) == NULL ) printf( "\nThe file 'test.csv' was not opened\n" ); else printf( "\nThe file 'test.csv' was opened\n" ); //schleife bis zum ende //read line while(fgetc(stream) != EOF) //bis zum fileende durchlaufen { line[200] = fgetc(stream); while (fgetc(stream) != '\n');//bis zum zeilenende durchlaufen { if( fgets( line, 200, stream ) == NULL) printf( "fgets error\n" ); else printf( "\n%s\n", line); } } fclose( stream ); } else printf( "\nThe file 'cAir_Plus_Beispiel.csv' was not opened\n" ); /* Close stream */ if( fclose( stream ) ) printf( "\nThe file 'Air_Plus_Beispiel.csv' was not closed\n" ); /* All other files are closed: */ numclosed = _fcloseall( ); printf( "\nNumber of files closed by _fcloseall: %u\n", numclosed ); break; case 2: printf("********** Vodafone **********\n"); break; case 3: printf("********** Programm wird beendet **********\n"); break; default : printf("********** Falsche Eingabe! **********\n"); break; } system("pause"); }
so, nun hab ich das mit der schleife *fg*
und nuuuuuuuuuuuuu?
-
Und nun kannst du die Schleife(n), die du gemacht hast über den Haufen schmeißen und nochmal drüber nachdenken.
Ok so gemein bin ich auch wieder nicht. Du hast das ganze viel zu umständlich gemacht und leider auch falsch.
Erstmal zu fgets(). fgets() liest aus einer Datei Zeichen ein und zwar bis zum nächsten Zeilenumbruch (\n), bis zum Dateiende (letzte Zeile) oder bis die maximale Einleselänge erreicht wird (bei dir ist das 100 = Größe deiner Variablen line). Zurückgegeben wird von fgets() die Anzahl der eingelesenen Zeichen und im Fehlerfall 0 (dazu zählt auch der Fall, wenn der Dateizeiger am Ende der Datei steht und man versucht etwas zu lesen).
So und nun, was du genau tun sollst:
Lese eine Zeile ein und gib diese aus solange das Dateiende nicht erreicht wurde.Das solltest du als Quellcode nun schreiben. Kleiner Tipp: Es dürften nur 2 Codezeilen sein (Zeilen nur mit Klammern nicht mitgezählt ;))
-
mmmh...mal ganz dreist gefragt, kannst du da an den quelltext nicht mal bissl rumfuschen? *wegrennt*
also die eine schleife ist überflüssig wenn ich fgets nehme anstatt fgetc
-
Die ganze Schleife stimmt schlicht und ergreifend nicht. Mal davon abgesehen, dass sie einen typischen Bufferoverflow enthält, der sich ganz böse äußern kann.
Lass dir nochmal den Satz durch den Kopf gehen und versuch ihn in C-Code umzusetzen:
Solange das Dateiende nicht erreicht ist, lese eine Zeile ein und gib diese am Bildschirm aus.Die Schlüsselwörter hab ich dir markiert.
Nochmal zu dem was du wissen solltest.
fgets() liest eine Zeile aus der Datei ein und gibt 0 zurück, wenn ein Fehler aufgetreten ist oder das Dateiende erreicht (gelesen) wurde.
-
#include <stdio.h> #include <string.h> #define INPUTFILE "Air_Plus_Beispiel.csv" #define OUTPUTFILE "test.csv" #define DELIM ";" int main (void) { FILE * input_stream, *output_stream; char line[BUFSIZ]; char *tokens[BUFSIZ]; int i; char * temptok; input_stream = fopen( INPUTFILE, "r"); // Eingabe oeffnen if (input_stream == NULL) { printf( "\nThe file '%s' was not opened\n", INPUTFILE ); exit(2); }; output_stream = fopen( OUTPUTFILE, "w"); //Ausgabe oeffnen if (output_stream == NULL) { printf( "\nThe file '%s' was not opened\n", OUTPUTFILE ); exit(2); }; while (!feof(input_stream)) { //Solange kein End-Of-File in der Eingabe... fgets (line, BUFSIZ, input_stream); i = 0; temptok = line; while ( (tokens[i] = strtok(temptok, DELIM)) != NULL) //strtok erwartet folgende Parameter: //temptok ist die zu splittende Zeile beim 1. Aufruf und NULL bei nachfolgenden Aufrufen; //der zweite Parameter sind die Grenzen der Tokens // Konstante DELIM oben auf ";" definiert //strtok gibt einen Zeiger auf den nächsten Token zurück oder NULL, wenn kein Token mehr da ist //(String zu Ende tokenisiert) //weise tokens[i] die Adresse des nächstens Tokens zu; wenn die Adresse nicht NULL ist, mache Folgendes: ... { temptok = NULL; i++; }; fprintf (output_stream, "%s;\n",tokens[3]); fprintf (output_stream, "%s;\n",tokens[4]); fprintf (output_stream, "%s;\n",tokens[5]); fprintf (output_stream, "%s;\n",tokens[13]); fprintf (output_stream, "%s;\n",tokens[17]); fprintf (output_stream, "%s;\n",tokens[18]); fprintf (output_stream, "%s;\n",tokens[19]); fprintf (output_stream, "%s;\n",tokens[25]); fprintf (output_stream, "%s;\n",tokens[27]); fprintf (output_stream, "%s;\n",tokens[31]); fprintf (output_stream, "%s;\n",tokens[38]); }; fclose (output_stream); fclose (input_stream); return (0); };
yeah
so, nun muss es das noch nebeneinander schreiben, also da wo ich die eine zeile eingelesen habe, soll auch in einer zeile ausgegeben werden. wo ist der haken?
-
\n erzeugt einen Zeilenumbruch ;).
Richtige Lösung des Ganzen. Bist du selber dahintergekommen oder hattest du Hilfestellung (außer von mir ;))?
-
Ich hätt auch im Zweifel die vielen fprintfs durch etwas in der Art ersetzt:
/* auszugebende felder */ int af[] = { 3, 4, 5, 13, 17, 18, 19, 25, 27, 31, 38, -1 }; int i; /* ... */ for(i = 0; af[i] >= 0; ++i) fprintf(output_stream, "%s;\n", tokens[af[i]]);
Das ist nachher einfacher erweiterbar, wenn du z.B. mal andere Felder ausgeben willst.
-
Whoops, das \n aus dem Formatstring muss natürlich raus, wenns in eine Zeile soll:
for(i = 0; af[i] >= 0; ++i) fprintf(output_stream, "%s;", tokens[af[i]]); fputc('\n', output_stream); /* Nach Ende der Zeile einen Zeilenumbruch raus schreiben*/
-
@AJ, hatte hilfe, allein wär ich nie so weit gekommen...
-
noch eine frage. ich muss ja trotzdem noch dies in das hauptmenü einbauen.
einfach so wie ich ganz am anfang angefangen hatte? also mit case arbeiten?
-
Troja2k schrieb:
noch eine frage. ich muss ja trotzdem noch dies in das hauptmenü einbauen.
einfach so wie ich ganz am anfang angefangen hatte? also mit case arbeiten?
Ja.
Dachte mir schon, dass du dabei Hilfe hattest. Ich hoffe du hast auch was draus gelernt. Hast du auch verstanden was da gemacht wird?
-
ja, bin eben nochmal teil für teil durchgegangen und hab hinter fast jede zeile einen kommentar geschrieben *g*
bin auf jedenfall dankbar, das es foren wie diese gibt
-
hallo ihr, besonders AJ *g*
ich brauch nochmal hilfe. um alles zu verstehen. wieso da nun ein pointer ist etc.
nochmal mein code bis jetzt:
#include <stdio.h> #include <string.h> #define INPUTFILE "Air_Plus_Beispiel.csv" //inputfile wird definiert #define OUTPUTFILE "test.csv" //outputfile wird definiert #define DELIM ";" //ab ; neu int main (void) { FILE * input_stream, *output_stream; //<-- ? char line[BUFSIZ]; //<-- ? char *tokens[BUFSIZ]; //<-- ? int i; char * temptok; //<-- ? char file; printf("********** Datei-Auswahl **********\n\n"); printf("1. Airplus\n"); printf("2. Vodafone\n"); printf("3. Beenden\n\n"); printf("Bitte waehlen Sie nun, welche Datei sie verarbeiten wollen.\n\n"); printf("Ihre Eingabe: "); scanf("%i",&file); printf("\n\n\n"); switch(file) { case 1: printf("********** Airplus **********\n"); input_stream = fopen( INPUTFILE, "r"); // Eingabe oeffnen (lesen) if (input_stream == NULL) //bei nicht vorhandener datei... { printf( "\nThe file '%s' was not opened\n", INPUTFILE );//fehlermeldung exit(2); }; output_stream = fopen( OUTPUTFILE, "a"); //Ausgabe oeffnen (anhängen) if (output_stream == NULL) //bei nicht vorhandener datei... { printf( "\nThe file '%s' was not opened\n", OUTPUTFILE );//fehlermeldung exit(2); }; while (!feof(input_stream)) //Solange kein End-Of-File in der Eingabe... { fgets (line, BUFSIZ, input_stream); //<-- ? i = 0; temptok = line; //<-- ? while ( (tokens[i] = strtok(temptok, DELIM)) != NULL) //strtok erwartet folgende Parameter: //temptok ist die zu splittende Zeile beim 1. Aufruf und NULL bei nachfolgenden Aufrufen; //der zweite Parameter sind die Grenzen der Tokens // Konstante DELIM oben auf ";" definiert //strtok gibt einen Zeiger auf den nächsten Token zurück oder NULL, wenn kein Token mehr da ist //(String zu Ende tokenisiert) //weise tokens[i] die Adresse des nächstens Tokens zu; wenn die Adresse nicht NULL ist, mache Folgendes: ... { temptok = NULL; i++; }; //schreiben in datei fprintf (output_stream, "\n%s;",tokens[3]); fprintf (output_stream, "%s;",tokens[4]); fprintf (output_stream, "%s;",tokens[5]); fprintf (output_stream, "%s;",tokens[13]); fprintf (output_stream, "%s;",tokens[17]); fprintf (output_stream, "%s;",tokens[18]); fprintf (output_stream, "%s;",tokens[19]); fprintf (output_stream, "%s;",tokens[25]); fprintf (output_stream, "%s;",tokens[27]); fprintf (output_stream, "%s;",tokens[31]); fprintf (output_stream, "%s;",tokens[38]); }; //schließen der beiden datein fclose (output_stream); fclose (input_stream); break; case 2: printf("********** Vodafone **********\n"); break; case 3: printf("********** Programm wird beendet **********\n"); break; default : printf("********** Falsche Eingabe! **********\n"); break; } system("pause"); }
AJ, kannst du das programm nachvollziehen und evtl kommentare dazu schreiben, was genau in den einzelnen zeilen passiert? ich verlier wiedermal den überblick
hab nun das, wo ich wirklich mir nicht viel bei denken kann mit "//<-- ?" beschrieben
-
OK
#include <stdio.h> #include <string.h> #define INPUTFILE "Air_Plus_Beispiel.csv" //inputfile wird definiert #define OUTPUTFILE "test.csv" //outputfile wird definiert #define DELIM ";" //ab ; neu int main (void) { FILE * input_stream, *output_stream; //Dateizeiger, zeigt auf Informationen über eine geöffnete Datei (nach fopen()) char line[BUFSIZ]; //Speicherbereich für eingelesene Zeile char *tokens[BUFSIZ]; //Zeigerarray zum Speichern der Zeiger auf die einzelnen Tokens int i; char * temptok; //Hilfszeiger für strtok() char file; printf("********** Datei-Auswahl **********\n\n"); printf("1. Airplus\n"); printf("2. Vodafone\n"); printf("3. Beenden\n\n"); printf("Bitte waehlen Sie nun, welche Datei sie verarbeiten wollen.\n\n"); printf("Ihre Eingabe: "); scanf("%i",&file); printf("\n\n\n"); switch(file) { case 1: printf("********** Airplus **********\n"); input_stream = fopen( INPUTFILE, "r"); // Eingabe oeffnen (lesen) if (input_stream == NULL) //bei nicht vorhandener datei... { printf( "\nThe file '%s' was not opened\n", INPUTFILE );//fehlermeldung exit(2); }; output_stream = fopen( OUTPUTFILE, "a"); //Ausgabe oeffnen (anhängen) if (output_stream == NULL) //bei nicht vorhandener datei... { printf( "\nThe file '%s' was not opened\n", OUTPUTFILE );//fehlermeldung exit(2); }; while (!feof(input_stream)) //Solange kein End-Of-File in der Eingabe... { fgets (line, BUFSIZ, input_stream); //liest eine Zeile von einer Datei ein i = 0; temptok = line; //weißt die gespeicherte Adresse in line auf temptok zu; temptok zeigt somit auf die gleiche Adresse wie line while ( (tokens[i] = strtok(temptok, DELIM)) != NULL) //strtok erwartet folgende Parameter: //temptok ist die zu splittende Zeile beim 1. Aufruf und NULL bei nachfolgenden Aufrufen; //der zweite Parameter sind die Grenzen der Tokens // Konstante DELIM oben auf ";" definiert //strtok gibt einen Zeiger auf den nächsten Token zurück oder NULL, wenn kein Token mehr da ist //(String zu Ende tokenisiert) //weise tokens[i] die Adresse des nächstens Tokens zu; wenn die Adresse nicht NULL ist, mache Folgendes: ... { temptok = NULL; i++; }; //schreiben in datei fprintf (output_stream, "\n%s;",tokens[3]); fprintf (output_stream, "%s;",tokens[4]); fprintf (output_stream, "%s;",tokens[5]); fprintf (output_stream, "%s;",tokens[13]); fprintf (output_stream, "%s;",tokens[17]); fprintf (output_stream, "%s;",tokens[18]); fprintf (output_stream, "%s;",tokens[19]); fprintf (output_stream, "%s;",tokens[25]); fprintf (output_stream, "%s;",tokens[27]); fprintf (output_stream, "%s;",tokens[31]); fprintf (output_stream, "%s;",tokens[38]); }; //schließen der beiden datein fclose (output_stream); fclose (input_stream); break; case 2: printf("********** Vodafone **********\n"); break; case 3: printf("********** Programm wird beendet **********\n"); break; default : printf("********** Falsche Eingabe! **********\n"); break; } system("pause"); }
Funktioniert dein Programm eigentlich fehlerfrei? Zumindest an einer Stelle dürfte was falsch laufen. Schau dir mal deine Ausgabedatei an, speziell die letzten zwei Zeilen.
-
ja, so ganz funktioniert es noch nicht
beim schreiben in die neue datei kommen ein paar sachen ein wenig "komisch" an *grübel*
-
Also ein Fehler liegt schon mal daran, dass du den Rückgabewert von fgets() nicht überprüfst. Auch wenn fgets() die letzte Zeile in der Datei gelesen hat, erkennt feof() noch nicht, dass das Dateiende erreicht wurde. Erst wenn das Dateiende "gelesen" wird. Und in dem Fall liefert fgets() 0 zurück. Du musst also den Rückgabewert von fgets() abprüfen, ob er ungleich 0 ist. Wenn ja, dann soll der Code darunter ausgeführt werden, wenn nein, dann nicht.
Dann kommt es mir noch mit dem tokens Array komisch vor. Daraus solltest du am besten ein zweidimensionales Array machen:
char tokens[ANZ_SPALTEN][BUFSIZ];
Zusätzlich brauchst du dann noch einen Zeiger wie temptok (aber nicht temptok selber benutzen).
Den Rückgabewert von strtok weißt du dann auf den neuen Zeiger zu und in der Schleife kopierst du per strcpy() den Inhalt auf den der neue Zeiger zeigt in das tokens-array.
Also so:
... char tokens[ANZ_SPALTEN][BUFSIZ]; char *akt_token; //neuer Zeiger, der auf das aktuelle Token zeigt ... for(i = 0; (akt_token = strtok(temptok, DELIM)) != NULL && i < ANZ_SPALTEN; ++i) { strcpy(tokens[i], akt_token); temptok = NULL; } ...
-
und wo genau muss ich
for(i = 0; (akt_token = strtok(temptok, DELIM)) != NULL && i < ANZ_SPALTEN; ++i) { strcpy(tokens[i], akt_token); temptok = NULL; }
jetzt einsetzen?