DAtei öffnen --- auslesen
-
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?
-
wird das mit dem 2 dimensionalen array nicht viel komplizierter für mich?
oder muss ich wirklich NICHTS weiter ändern im code, außer was du mir geschrieben hattest?
-
AJ schrieb:
OK
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.
was genau meintest du damit?
-
Troja2k schrieb:
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?
Das ersetzt deine bisherige strtok() Schleife
Troja2k schrieb:
wird das mit dem 2 dimensionalen array nicht viel komplizierter für mich?
oder muss ich wirklich NICHTS weiter ändern im code, außer was du mir geschrieben hattest?
Es wird dadurch nicht wirklich komplizierter, aber auf jeden Fall sicherer.
Mehr musst du wirklich nicht ändern. Nur eben das behandeln der Daten mit strtok() und die Abfrage vom Rückgabewert von fgets().
Troja2k schrieb:
AJ schrieb:
OK
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.
was genau meintest du damit?
Normalerweise müssten die zwei letzten Zeilen genau gleich sein und es müsste eine Zeile mehr existieren als in der Quelldatei.
Wie gesagt erst wenn fgets() (oder eine andere Lesefunktion) das Dateiende auch wirklich gelesen hat, erkennt feof() das Dateiende.
In deinem Fall würde das heißen, dass du die letzte Zeile einliest (der Dateizeiger steht vor dem Dateiende) und auswertest, dann kommt feof() und erkennt nicht, dass der Dateizeiger schon am Dateiende steht, da das Dateiende noch nicht gelesen wurde. Also wird die Schleife nochmal ausgeführt. fgets() liest nun das Dateiende und gibt 0 als Erkennung eines "Fehlers" zurück. Da du das aber nicht auswertest wird der Quellcode ganz normal weiterverarbeitet, d. h. die zuvor gelesene Zeile wird nochmal fälschlicherweise verarbeitet und erst jetzt erkennt feof(), dass das Dateiende erreicht 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; //Dateizeiger, zeigt auf Informationen über eine geöffnete Datei (nach fopen()) char line[BUFSIZ]; //Speicherbereich für eingelesene Zeile //char line [BUFSIZ]; //Zeigerarray zum Speichern der Zeiger auf die einzelnen Tokens int i; char * temptok; //Hilfszeiger für strtok() char file; char tokens[ANZ_SPALTEN][BUFSIZ]; char *akt_token; //neuer Zeiger, der auf das aktuelle Token zeigt 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) { 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) { 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; for(i = 0; (akt_token = strtok(temptok, DELIM)) != NULL && i < ANZ_SPALTEN; ++i) { strcpy(tokens[i], akt_token); temptok = 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: ... //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"); }
mmh..nu gibbet fehler
16 `ANZ_SPALTEN' undeclared (first use in this function)
-
Ich dachte du würdest verstehen, was ich mit ANZ_SPALTEN bezwecke. Kleiner Tipp: Es ist sowas ähnliches wie DELIM oder BUFSIZ ;).
-
ähm *ggg* nein, weiß ich nicht. kannte ja DELIM und BUFSIZ vorher nicht. hab noch nie was davon gehört gehabt
-
Aber für was es ist, kannst du dir schon denken, oder??
Du musst es im Prinzip nur so machen wie bei DELIM:
//Anzahl der Spalten in einer Zeile #define ANZ_SPALTEN
Hinter ANZ_SPALTEN musst du natürlich noch den passenden Wert schreiben ;).
-
*wieder AJ belästigt*
ja, für DENIM hab ich ; gesetzt, welches ja immer am "ende" eines wertes steht.
aber was steht nach unten hin
-
Was nach unten hin steht?
Irgendwie, glaub ich, verstehst du nicht was ich meine.
ANZ_SPALTEN ist kein Trenner. Überleg doch mal was ANZ_SPALTEN heißt. Eigentlich brauchst du ja nur den Kommentar, den ich extra dazugeschrieben habe lesen. Wenn du weißt was es heißt (was eigentlich mehr als offensichtlich ist), dann weißt du auch welchen Wert bzw. welche Zahl du hinschreiben musst.
-
*grml*
#define ANZ_SPALTEN "45"
wahrscheinlich auch falsch, weil das guckt dann ja wo eine 45 steht, oder?
die datei die ich einlese hat 45 spalten
-
Jetzt bist du der Sache schon ganz nahe.
Der Compiler schaut aber nicht ob da irgendwo eine 45 steht, sondern er schaut, ob da ANZ_SPALTEN steht und ersetzt das momentan durch "45" (inclusive Anführungszeichen). Allerdings wirst du da noch Fehler bekommen, weil es so keinen Sinn macht (so würde es der Compiler ersetzen; BUFSIZ würde er natürlich auch durch eine Zahl ersetzen ;)):... char tokens["45"][BUFSIZ]; ...
Lass einfach die Anführungszeichen weg und schon passt es :).
(so sollte es dann vom Compiler ersetzt werden)
... char tokens[45][BUFSIZ]; ...
So würde es doch auch richtiger aussehen, oder?
-
so, es läuft
du bist klasse!
noch eine frage.
wenn ich jetzt die csv datei mitexel öffne, um zu gucken, wie das dort hineingeschrieben wurde, dann geht es immernoch nicht wirklich . d.h. es ist immernoch verschoben.soll ich dir die datei mal per email schicken, damit du siehst wie ich es meine?
-
Ja mach mal. Kann sie mir aber erst morgen vornehmen, sorry.
Schau dir die Datei einfach mal mit dem notepad (Start -> Ausführen -> notepad) an, vielleicht findest du dann den Fehler.
-
kann nichts auffälliges finden, was daran schuld sein könnte.
hab dir die datein mal zum web.de postfach geschickt.
-
nochmal genauer :
- in der ersten zeile gibt mein blödes prog ein paar sachen doppelt aus.
- und es schreibt das letzte eingelesene element in eine neue zeile, was das ganze durcheinander bringt
-
Hallo,
so spontan würde ich sagen die Zeile
fprintf (output_stream, "\n%s;",tokens[3]); ist falsch,
das haut zwar bei allen nachfolgenden Zeilen hin,bei der allerersten ist der
Zeilenwechsel aber überflüssig,ich würde ihn eher an die letzte frprintf Anweisung anhängen,bzw. das Zeilenende seperat schreiben.
Ich bin mir auch nicht 100% sicher ob ein \n reicht,vielleicht ist auch ein \n\r notwendig.Peter
-
#include <stdio.h> #include <string.h> #define INPUTFILE "Air_Plus_Beispiel.csv" #define OUTPUTFILE "test.csv" #define DELIM ";" #define ANZ_SPALTEN 45 #define LINE_LENGTH 1024 int main (void) { FILE * input_stream, *output_stream; //Dateizeiger, zeigt auf Informationen über eine geöffnete Datei (nach fopen()) char line[LINE_LENGTH]; //Speicherbereich für eingelesene Zeile //char line [LINE_LENGTH]; //Zeigerarray zum Speichern der Zeiger auf die einzelnen Tokens int i; char * temptok; //Hilfszeiger für strtok() char file; char tokens[ANZ_SPALTEN][LINE_LENGTH]; char *akt_token; //neuer Zeiger, der auf das aktuelle Token zeigt 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) { 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) { printf( "\nThe file '%s' was not opened\n", OUTPUTFILE );//fehlermeldung exit(2); }; while (!feof(input_stream)) //Solange kein End-Of-File in der Eingabe... { if( fgets (line, LINE_LENGTH, input_stream) ) //liest eine Zeile von einer Datei ein { temptok = line; for(i = 0; (akt_token = strtok(temptok, DELIM)) != NULL && i < ANZ_SPALTEN; ++i) { strcpy(tokens[i], akt_token); temptok = 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: ... //schreiben in datei fprintf (output_stream, "%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\n",tokens[38]); } //if( fgets(...) ) } //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; } printf("Drücken Sie ENTER"); getchar(); }
das ist nun die aktuellste version.
nur verhaut der kompiler da einiges...anfang klappt es, danach würfelt er einiges durcheinander
-
Hallo,
ich vermute mal bis Zeile 1 letzer Eintrag stimmts,danach mach er mist?Oder ab welcher stelle genau?
Peter
-
ja genau, erste zeile stimmt, aber danach bringt er einiges durcheinander.
jemand von einen andern board hat es mal unter seinen linux compiler laufen lassen und da ging es wohl ohne probleme.
werde gleich mal mir noch andere compiler runterladen. denn ich find sonst keinen fehler mehr