CSV - Datei einlesen

23/12/2009 - 13:42 von Ralf Hackmann | Report spam
Hallo,

ich muss 2 CSV-Dateien auf Übereinstimmung bestimmter Felder prüfen
und das Ergebnis als 3. CSV Datei ausgeben.

Um den Einlesevorgang zu testen, habe ich ein kleines Programm
erstellt, dass die erste CSV einliest und direkt wieder ausgibt. Hier
treten schon Schwierigkeiten auf.

CSV Datei
20091110;20091106;20090713;11090365;640;VorlageBaugruppen;1,0;50;
20091110;20091106;20090713;11090365;640;VorlageBaugruppen;1,0;50;
20091111;20091109;20091111;11090644;556;a_grlitzskalarbasiccomada;
5,0;50;

CODE:
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char **argv) {
FILE *CSV;
char ar1_artbez[40];
int lip_liefwo, lip_bestterm, lip_wtermin, lip_aufnr, lip_kunde,
lip_diffme, lip_priorita;

if(argc < 2) {
fprintf(stderr, "Verwendung : %s datei.csv", *argv);
return EXIT_FAILURE;
}
CSV = fopen(argv[1], "r");
if(NULL == CSV) {
fprintf(stderr, "Fehler beim Oeffnen ...");
return EXIT_FAILURE;
}
/* Nun lesen Sie formatiert von der Datei ein ... */
while((fscanf(CSV,"%d;%d;%d;%d;%d;%s;%d,0;%d;",
&lip_liefwo, &lip_bestterm ,&lip_wtermin, &lip_aufnr,
&lip_kunde ,&ar1_artbez, &lip_diffme ,&lip_priorita)) != EOF )
fprintf(stdout,"lip_liefwo:%d | lip_bestterm:%d | lip_wtermin:
%d | lip_aufnr:%d | lip_kunde:%d | ar1_artbez:%s | lip_diffme:%d |
lip_priorita:%d",
lip_liefwo, lip_bestterm, lip_wtermin, lip_aufnr, lip_kunde,
ar1_artbez, lip_diffme, lip_priorita);
return EXIT_SUCCESS;
}
Anmerkung: ;%d,0; weil in der csv an der Stelle immer ,0 steht

AUSGABE
lip_liefwo:20091110 | lip_bestterm:20091106 | lip_wtermin:20090713 |
lip_aufnr:11090365 | lip_kunde:640 | ar1_artbez:VorlageBaugruppen;
1,0;50; | lip_diffme:1074308878 | lip_priorita:-1073742223
lip_liefwo:20091110 | lip_bestterm:20091106 | lip_wtermin:20090713 |
lip_aufnr:11090365 | lip_kunde:640 | ar1_artbez:VorlageBaugruppen;
1,0;50; | lip_diffme:1074308878 | lip_priorita:-1073742223
lip_liefwo:20091111 | lip_bestterm:20091109 | lip_wtermin:20091111 |
lip_aufnr:11090644 | lip_kunde:556 |
ar1_artbez:a_grlitzskalarbasiccomada;5,0;50; | lip_diffme:1074308878 |
lip_priorita:-1073742223

fscanf liest anscheinend ar1_artbez bis zum Zeilenende und die Werte
für lip_diffme und lip_priorita kommen aus dem Nirvana!?

Original sieht die CSV wiefolgt aus
20091110;20091106;20090713;11090365;640;Vorlage Baugruppen;1,0;50;
20091110;20091106;20090713;11090365;640;Vorlage Baugruppen;1,0;50;
20091111;20091109;20091111;11090644;556;a_grlitzskalarbasiccomada;
5,0;50;

D.H. in ar1_artbez können durchaus Leerzeichen vorhanden sein.
Jedoch làuft mit dieser CSV das Programm in eine Endlosschleife.

Was mache ich falsch?

Oder làuft das darauf hinaus, dass ich jedes Zeichen einzel einlesen
muss und die CSV "parsen" muss.

Gruss

Ralf
 

Lesen sie die antworten

#1 Stefan Reuther
23/12/2009 - 14:08 | Warnen spam
Ralf Hackmann wrote:
while((fscanf(CSV,"%d;%d;%d;%d;%d;%s;%d,0;%d;",
&lip_liefwo, &lip_bestterm ,&lip_wtermin, &lip_aufnr,
&lip_kunde ,&ar1_artbez, &lip_diffme ,&lip_priorita)) != EOF )


[...]
fscanf liest anscheinend ar1_artbez bis zum Zeilenende und die Werte
für lip_diffme und lip_priorita kommen aus dem Nirvana!?



'%s' liest bis zum nàchsten Whitespace. Du willst vermutlich '%['.
Außerdem empfiehlt es sich, eine Maximalgröße anzugeben.

Dass 'fscanf' die letzten zwei Parameter nicht gelesen hat, hàtte dir
ansonsten der Rückgabewert verraten.

Oder làuft das darauf hinaus, dass ich jedes Zeichen einzel einlesen
muss und die CSV "parsen" muss.



Das ist tendenziell eine gute Idee, weil du somit auf Ungereimtheiten
viel besser reagieren kannst. Wenn 'fscanf' sagt "ich hab 3 Felder
gelesen", weißt du nicht, wo der Fehler lag und wie du die nàchste Zeile
findest. Und selbst, wenn 'fscanf' dir 8 Felder liefert, könnten die auf
zwei Zeilen a 4 Felder verteilt gelegen haben. Schließlich gibt es auch
noch Programme, die CSV mit Quotes schreiben, um z.B. Strings mit
Leerzeichen und/oder Semikola drin darstellen zu können.


Stefan

Ähnliche fragen