1. Diese Seite verwendet Cookies. Wenn du dich weiterhin auf dieser Seite aufhältst, akzeptierst du unseren Einsatz von Cookies. Weitere Informationen

Daten aus CSV Datei mit ANS C lesen

Dieses Thema im Forum "C/C++" wurde erstellt von M0zart, 11. Januar 2017.

  1. M0zart

    M0zart Grünschnabel

    Hallo, ich bin relativ neu hier und noch nicht so fit in C. Ich bin auf ein Problem gestoßen, wobei mir bisher keiner weiterhelfen konnte. Ich hab auch gesehen, das ziemlich viel zu finden ist über Datei auslesen usw., aber wirklich weitergeholfen hat es mir nicht.

    Zu meinem Problem: Ich muss in ANS C aus einer CSV Datei Werte lesen. Ich kenn jetzt den unterschied zwischen ANS C und "normal" C nicht wirklich. Ich hab auch schon ein Beispielprogramm bekommen und auch ausprobiert aber irgendwie funktioniert das ganze nicht richtig.

    Dazu sei noch gesagt, das ganze wird in einem Programm von Siemens (WinCC V7.3) verarbeitet, deswegen auch ANS C. Und das Programmbeispiel ist auch von Siemens.

    Ich bekomm meine gewünschte Datei geöffnet, nur wenn ich versuche irgendwas raus zu lesen, bekomm ich folgenden Fehler: general protection fault (Fehlermeldung vom WinCC). Der Compiler übersetzt alles wunderbar nur mit 3 Warnungen (Anhang).

    Ich hoffe ihr könnt mir helfen... Vielen Dank schon einmal im vorraus
     

    Anhänge:

  2. sheel

    sheel I love Asm Administrator

    Hi

    bitte Code als Text reinkopieren, in [code=c]hier der code[/code]

    Die Sprache C ist seit Erfindung nicht gleich geblieben, sondern wurde mehrmals erweitert/geändert (also nicht nur Compiler usw., sondern die Sprache selber, welche Symbole und Funktionen usw. es gibt).
    Es gibt
    • das "Ur-C", wie es von Kernighan und Ritchie irgendwann vor 1980 erfunden wurde
    • C89 (1989, auch ANSI-C genannt)
    • C99 (1999)
    • und C11 (2011)
    Die neueren Varianten sind für den Programmierer im Wesentlichen besser (weniger umständlich usw.), wenn es um neue Programme geht. Die älteren Varianten sind trotzdem noch wichtig,
    • wenn es um alte bestehende Programme geht (die sehr oft in den neueren Varianten auch richtig sind, aber nicht immer)
    • wenn man aus irgendeinem Grund keine neue Variante verwenden darf (Chef der die Neuerungen nicht lernen will und deshalb der ganzen Firma die Verwendung verbietet, oder Ähnliches...)
    • oder wenn man, wie du anscheinend, keinen passenden Compiler hat.
    In C89 programmieren ist jedenfalls nicht lustig, wenn man C11 auch haben könnte. Aber wenns sein muss...

    So, zum Fehler:
    Bisher aufgefallen ist mir, dass du "\0" verwendest, was in C ein ganzer String bzw. der Pointer darauf ist. '\0' wie im Beispiel ist ein einzelner Buchstabe (bzw. Byte).

    Und "Warnungen" von C-Compilern sind oft schlimmer als die ganzen Fehler. Immer versuchen, alle Warnungen loszuwerden, bzw. zu verstehen warum sie da ist.
     
    cwriter und M0zart gefällt das.
  3. M0zart

    M0zart Grünschnabel

    Vielen dank erst einmal für die schnelle Hilfe Sheel. Hier wie gewünscht der Code
    Code (C):
    1. #include "apdefap.h"
    2.  
    3. int gscAction( void )
    4. {
    5. #define MaxLineLength 80
    6.  
    7. FILE *fpFile;
    8. char *strTag, *strValue, *pTmp;
    9. char buffer[MaxLineLength];
    10. double dVal;
    11. fpFile = fopen("c:\\Users\\Desktop\\Mappe1.csv", "r");
    12. printf("C-Skript: lese Datei: Mappe1.csv\n");
    13. if(fpFile !=NULL)
    14. {
    15.      while(fgets(buffer,MaxLineLength, fpFile))
    16.      {
    17.           strTag=buffer;
    18.           pTmp = strchr(buffer,(int)';');
    19.           *pTmp='\0';
    20.           strValue=++pTmp;
    21.           strValue[strlen(strValue)-1]='\0';
    22.  
    23.           pTmp=strchr(strValue,(int)',');
    24.           if(pTmp !=NULL){
    25.              *pTmp='.';
    26.           }
    27.  
    28.           sscanf (strValue, "%lf", &dVal);
    29.           //SetTagDouble(strTag,dVal);
    30.           printf("%s Value: %lf\r\n", strTag, dVal);
    31.      }
    32.      fclose(fpFile);
    33. } else{
    34. printf("Error: File not found!\n");
    35. }
    36.  
    37. return 0;
    38. }
    Ich hab das geändert mit den " und siehe da es funktioniert. Jetzt hab ich das Problem, dass meine Zahl praktisch gerundet oder abgeschnitten wird... Ich weiß nicht genau was da passiert. Und zwar macht das Programm aus der Zahl 1,1 eine 1.0000000 und das gleiche für 2,2 -> 2.00000.
     

    Anhänge:

    • C.PNG
      C.PNG
      Dateigröße:
      2,1 KB
      Aufrufe:
      3
    sheel gefällt das.
  4. M0zart

    M0zart Grünschnabel

    Den Teil versteht ich auch noch nicht wirklich. Ich weiß das ich Zeile für Zeile praktisch lese. Aber was passiert da genau?
     
  5. sheel

    sheel I love Asm Administrator

    Hm ... wie schaut denn eine CSV-Zeile bei dir genau aus?

    Zum fgets: Ein Einzelner aufruf von fgets liest eben eine Zeile aus der Datei fpFile, in den String buffer, aber maximal MaxLineLength Byte (weil buffer in dem Fall nicht mehr Platz hat; fgets weiß das aber nicht selber, deshalb auch übergeben).
    fgets hat aber auch noch einen Returnwert (den man theoretisch mit "varname = fgets(...)" einer Variable zuweisen könnte), und zwar den ersten Parameter (buffer) wenn alles funktioniert hat (als Pointer-/Speicher-Adresse, wie Strings in C eben gehandhabt werden), oder 0 (das nie als Adresse verwendet wird) wenn die Datei schon zu Ende ist oder irgendein anderer Fehler passiert ist.
    In dem Fall wird der Wert zwar keiner Variable zugewiesen, sondern als Schleifenbedingung im While verwendet - etwas seltsam (normal wären ja Vergleiche wie "a == b" oder "a < b", und keine einzelnen Werte), aber das kann man in C machen: 0 wird in dem Fall als falsch bzw. Schleife beenden verstanden, und alles andere als wahr bzw. weitermachen. Kann man zum Testen auch einfach so hinschreiben: while(1) wird ewig ausgeführt, und while(0) nie.
    Also kurz, solange fgets nicht 0 ergibt, also solange die Datei nicht zu Ende ist...
     
    Zuletzt bearbeitet: 11. Januar 2017
    M0zart gefällt das.
  6. cwriter

    cwriter Erfahrenes Mitglied

    1,1 ist auch keine Zahl - jedenfalls nicht in wissenschaftlicher Notation. Das wäre dann "1.1". Daher wird bei
    Code (C):
    1. strchr(strValue, (int)',');
    2. if(pTmp !=NULL){
    3.              *pTmp='.';
    4.           }
    auch das Komma zu einem Punkt gewechselt. Aber nur einmal. Daher:
    Die Casts von Zeichenliteralen auf int machen auch nicht wirklich viel Sinn - das ist nämlich Standard-Verhalten.

    Und:
    Hehe. Seuche...

    Gruss
    cwriter
     
    M0zart gefällt das.
  7. M0zart

    M0zart Grünschnabel

    Also das mit dem Komma durch Punkt hab ich verstanden, aber das macht er scheinbar nicht richtig. Für den Beispielcode ist in der CSV Datei folgender Inhalt:
    TagA; 1,1
    TagB; 2,2
    TagC; 3,3
    usw.

    Nochmals danke für die Erklärung, die hilft mir sehr weiter :D
     
  8. cwriter

    cwriter Erfahrenes Mitglied

    Und den Code hast du so bekommen?
    Seufz. Manche Leute müssen das Rad aber auch immer neu erfinden...
    Der gesamte Code liesse sich sehr viel leichter schreiben (mit ein paar Konzessionen, versteht sich):
    Code (C):
    1. setlocale(LC_NUMERIC, "de_DE");
    2. while(fscanf(fpFile, "%[^;]; %lf\n", strName, &strValue) == 2) // strName entsprechend ein Stringbuffer (kein "reiner" Pointer)
    3. {
    4.     //Werte eingelesen
    5. }
    6. setlocale(LC_NUMERIC, ""); //Reset auf (System-)Standard
    4 SLOC statt 8.
    Einziger "Nachteil": Die Zahlen müssen jetzt mit Kommata statt Dezimalpunkten eingegeben werden. Allerdings wäre das Vermischen von Zahlenformaten ohnehin Blödsinn. Falls du dennoch erlauben wolltest, dass die Zahlenformate gemischt sein dürfen, kannst du statt %lf einfach %s einlesen und dort die Kommata durch Punkte ersetzen.
    Übrigens ist das \r\n beim einen printf überflüssig - \n ist der Standard für Zeilenumbrüche (übrigens muss man nur dann auf \r\n achtgeben, wenn man die Datei binär öffnet - aber das ist eine andere Geschichte).

    Was sagt der Debugger bzw. das printf-Debugging?

    Gruss
    cwriter

    /EDIT: Die locales brachten mich auf die Idee, dass dein System schon Kommata erwartet... Was passiert, wenn du die Kommata nicht durch Punkte ersetzt?
     
    Zuletzt bearbeitet: 12. Januar 2017
    M0zart gefällt das.
  9. M0zart

    M0zart Grünschnabel

    Vielen Dann cwriter. Ja das ganze ist in der Siemens Sofware WinCC (Visualisierungsprogramm für die Industrie) erstellt und somit ist der Code auch von Siemens.
    Deswegen kann ich den Code nur ganz normal Debuggin (keine Ahnung was der printf Debugger ist) und da gibt er 0 Fehler 0 Warnungen aus.

    Also in meinem bestimmten Anwendungsfall muss ich aus einer csv Datei 2 Werte zurück schreiben. Deswegen brauch ich die Werte als float. Die csv von mir sieht wie folgt aus:
    Text;Text;Text;Text
    Zeitpunkt; Zahlenwert; Zahlenwert; Zahlenwert
    Zeitpunkt; Zahlenwert; Zahlenwert; zahlenwert
    Zeitpunkt; Zahlenwert; Zahlenwert; zahlenwert
    usw...

    Ich muss jetzt noch wissen wie ich die erste Zeile überspringe... weil wenn ich versuche einen Text als Zahl zu verwenden, wird der sehr wahrscheinlich meckern .... Und dann bräuchte ich letztendlich aus der zweiten Zeile einen Wert und aus der letzten. Das würde ich dann über einen Zähler oder so machen, sprich gucken wann der in der 2 Zeile ist und den Wert wegschreiben und wenn er am Schluss angekommen ist, hat er ja die letzte Zeile....
     
  10. cwriter

    cwriter Erfahrenes Mitglied

    Das ist kein Debuggen, sondern ein Kompilieren. Vereinfacht gesagt sagt dir der Compiler, was er nicht versteht (weil Syntaxfehler bestehen). Debuggen beginnt dann, wenn man syntaktisch korrekten Code hat (der Compiler versteht, was du willst), aber die Semantik nicht stimmt (du falsch ausgedrückt hast, was du wolltest).
    printf-Debugging heisst nur, dass du dir die Variablenwerte periodisch ausgeben lässt, um die Werte zu überprüfen (statt wie bei einem echten Debugger das Programm anzuhalten).

    Nur zum Kopieren musst du Strings nicht in (double) floats verwandeln.

    Dann kann der Matchstring auf "%[^;]; %lf; %lf; %lf\n" geändert werden. Das ist ja gerade das Tolle an scanf: Es ist sehr flexibel (was auch seine Nachteile hat, siehe vararg-Diskussion).

    Verstehe ich nicht. WinCC ist ja kein Compiler? Wurde die CSV-Datei in WinCC erstellt? Das wäre unerheblich - CSV ist CSV.

    Und wenn der Code von Siemens ist, dann würde mein Weltbild recht erschüttert...

    Wenn du die Spaltennamen nicht kennen willst, ja.
    Möglichkeiten sind fgets() und scanf("%*[^\n]"), wobei das Asterisk bedeutet, dass man das Gelesene nicht speichern will.

    Nö. Wahrscheinlich wird es eher Undefined Behavior sein (bzw. der Wert wird nicht in deine Variable eingetragen, und da du diese nicht definierst, kann irgendwas in der Variable stehen).

    Und aus dem Rest nix? Dann gäbe es wesentlich schnellere Möglichkeiten als mit einem Zähler (fseek() und Konsorten).

    Ja, das würde gehen.

    Gruss
    cwriter
     
    M0zart gefällt das.
  11. M0zart

    M0zart Grünschnabel

    Also sowohl die csv als auch der c Code wird in WinCC erstellt und verarbeitet. Das ist alles nur ein Umweg den ich gegen muss, weil Siemens das gerne kompliziert macht (langjährige Erfahrung).

    Ich hab eigentlich im WinCC eine Tabelle in der Werte aus einer Datenbank stehen. Jetzt ist die Tabelle variabel d.h. es kann irgendeine Zeitspanne ausgewählt werden und ich muss dann von dieser Zeitspanne den ersten und den letzten Wert raus suchen, um damit weiter zu rechnen. Jetzt ist das aber so, dass ich nicht auf die Datenbanken zugreifen kann, weil diese verschlüsselt sind. Deswegen wurde mir von Siemens geraten, das über einen Export Import zu machen :D... also erst Tabelle in csv exportieren und direkt wieder zu importieren.

    Export bekomm ich hin, das ist nur ein Klick, aber bei dem Import hapert es.

    Die zwei Werte die ich praktisch raus schreiben müssen dringend float sein, weil ich sonst im weiteren Verarbeitungsschritt Probleme habe bzw. nichts damit anfangen kann.

    Aber vielen vielen Dank, ihr habt mir sehr weitergeholfen. Ich Probier das ganze aus wenn ich wieder zu Hause bin (nächste Woche) und berichte dann.
     
  12. M0zart

    M0zart Grünschnabel

    Hallo cwriter,
    was meinst du damit genau? Ich bin immer noch unsicher was ich jetzt genau machen soll? Soll ich das fgets durch fscanf austauschen und bleibt der mittlere Teil erhalten:
    Code (C):
    1.           strTag=buffer;
    2.           pTmp = strchr(buffer,(int)';');
    3.           *pTmp='\0';
    4.           strValue=++pTmp;
    5.           strValue[strlen(strValue)-1]='\0';
    6.  
    7.           pTmp=strchr(strValue,(int)',');
    8.           if(pTmp !=NULL){
    9.              *pTmp='.';
    Mit fgets hol ich mir ja jede Zeile nach einander. Buffer ist die maximale Länge die ich mit übernehme (in dem Fall 80, hab ich ja bei MaxLineLength definiert). das übergebe ich praktisch strTag. Aber was ab
    Code (C):
    1. pTmp=strchr(buffer,(int)';');
    versteh ich nicht mehr wirklich. Ich denk da wird der ganze String (Ganze Zeile) aufgetrennt und zwar immer bei dem ';' Simikolon oder?
    das *pTmp='\0'; damit setzte ich am ende noch die \0, damit der weiß das hier ende ist?
    dann wird pTmp erst um eins erhöht und in strValue geschrieben (
    Code (C):
    1.  strValue=++pTmp;
    )?
    Code (C):
    1. strValue[strlen(strValue)-1]='\0';
    da bin ich wieder voll raus.
    und hier:
    Code (C):
    1.     pTmp=strchr(strValue,(int)',');
    2.           if(pTmp !=NULL){
    3.              *pTmp='.';
    ersetzt er einfach das Komma durch einen Punkt.

    in meinem strValue steht jetzt so gesehen jede Zelle von mir und wird ständig wieder überschrieben?

    Und wo bzw. wann wird da strTag beschrieben?
     
    Zuletzt bearbeitet: 18. Januar 2017
  13. cwriter

    cwriter Erfahrenes Mitglied

    Source Lines Of Code.
    (Der Code ist syntaktisch aufgeräumter, aber semantisch äquivalent).

    fscanf ersetzt fgets und sscanf (nur in Verbindung mit setlocale() ). Der Inhalt der Schleife bleibt damit nicht erhalten.

    Nein, das wäre die Funktionsweise von strtok().
    strchr könnte so implementiert sein:
    Code (C):
    1. const char* strchr(const char* str, const char* delim)
    2. {
    3. for(const char* it = str; it < str + strlen(str); it++)
    4. for(const char* it2 = delim; it2 < delim + strlen(delim); it2++)
    5. if(*it == *it2) return it;
    6. return (const char*)0;
    7. }
    Es gibt also die Position des ersten Zeichens in Delim innerhalb des Strings zurück. Der String wird aber NICHT verändert.
    Nein, du ersetzt das Semikolon mit 0 (strtok()-Behavior).
    Ja. pTmp zeigt zuerst auf den nächsten Teilstring, dann wird erhöht.

    Die Länge des 2. Strings wird um 1 gekürzt.

    Überschrieben.

    Gruss
    cwriter
     
    M0zart gefällt das.
  14. M0zart

    M0zart Grünschnabel

    Also ich hab mal jetzt jede Zeile von mir Ausgegeben und da hab ich folgendes raus:
    Code (C):
    1. #include "apdefap.h"
    2.  
    3. int gscAction( void )
    4. {
    5. #define MaxLineLength 80
    6.  
    7. FILE *fpFile;
    8. char *strTag, *strValue, *pTmp;
    9. char buffer[MaxLineLength];
    10. double dVal, dVal2, dVal3;
    11. int i=0;
    12.  
    13. fpFile = fopen("c:\\Users\\Desktop\\Mappe1.csv","r");
    14. printf("C-Skript: lese Datei: Mappe1.csv\n");
    15. if(fpFile !=NULL)
    16. {
    17.      while(fgets(buffer,MaxLineLength, fpFile))
    18.      {
    19.           i++;
    20.           strTag=buffer;
    21. printf("strTag1: %s   Buffer: %s\n", strTag, buffer);
    22.           pTmp = strchr(buffer,(int)';');
    23. printf("pTmp1: %s\n", pTmp);
    24.           *pTmp='\0';
    25. printf("pTmp2: %s\n", pTmp);
    26.           strValue=++pTmp;
    27. printf("strValue1: %s\n", strValue);
    28.           strValue[strlen(strValue)-1]='\0';
    29. printf("strValue2: %s\n", strValue);
    30.           pTmp=strchr(strValue,(int)',');
    31. printf("pTmp3: %s\n", pTmp);
    32.           if(pTmp !=NULL){
    33.              *pTmp='.';
    34. printf("pTmp4: %s\n", pTmp);
    35.           }
    36.           sscanf (strValue, "%lf", &dVal);
    37.           //SetTagDouble(strTag,dVal);
    38.           printf("%s Value: %lf pTmp: %s  strValue: %s \r\n", strTag, dVal, pTmp, strValue);
    39. printf("------------------------------------------Zeile: %d--------------------------------------------\n", i);
    40.      }
    41.      fclose(fpFile);
    42. } else{
    43. printf("Error: File not found!\n");
    44. }
    45.  
    46. return 0;
    47. }
    Im Anhang ist die Ausgabedatei. Wie man sieht, nimmer der Code die Nachkommastelle nicht mit. also er nimmt die Zahl vor dem Komma, ersetzt das Komma durch den Punkt, aber vernachlässigt die Nachkommastelle. Ich hab auch mal jetzt die csv Datei um eine Spalte ergänzt.

    und cwriter: wenn ich jetzt dieses strtok() von dir verwende, wird die Zeile ja immer bei dem Simikolon getrennt oder? Das heißt ich kann die ganze Zeile direkt so nehmen, dieses strtok() anwenden und direkt in Variablen speichern, sprich erste ist %s und dan %lf und noch ein %lf. Ich kenn ja den aufbau meiner csv. Die Spalten bleiben immer gleich nur die Anzahl der Zeilen variiert, aber das ist ja bei der Schleife egal.
     

    Anhänge:

    Zuletzt bearbeitet: 18. Januar 2017
  15. M0zart

    M0zart Grünschnabel

    das wär praktisch der Code den ich verwenden müsste oder? Aber was meinst du mit //Werte eingelesen? Da muss ich doch nichts merh machen, weil ich oben doch schon in strName und strValue schreibe oder nicht?
     
  16. M0zart

    M0zart Grünschnabel

    Also ich hab mal setlocale verwendet aber scheinbar nicht richtig. Sorry nochmal dafür das ich etwas länger brauche um das zu verstehen, aber wie gesagt, programmier eher selten mit C bzw. programmiere eigentlich garnicht.

    Code (C):
    1. #include "apdefap.h"
    2.  
    3. int gscAction( void )
    4. {
    5.  
    6. #define MaxLineLength 80
    7.  
    8. FILE *fpFile;
    9. char *strTag, *strValue, *pTmp;
    10. char buffer[MaxLineLength];
    11. double dVal, dVal2, dVal3;
    12. int i=0;
    13.  
    14. fpFile = fopen("c:\\Users\\Desktop\\Mappe1.csv","r");
    15. printf("C-Skript: lese Datei: Mappe1.csv\n");
    16. if(fpFile !=NULL)
    17. {
    18. setlocale(LC_NUMERIC, "de_DE");
    19. while(fscanf(fpFile, "%[^;]; %lf; lf\n", strTag, &dVal, &dVal2)==2)
    20. {
    21. //Werte eingelesen?
    22. }
    23. setlocale(LC_NUMERIC, "");
    24.  
    25.           }
    26.  
    27.           sscanf (strValue, "%lf", &dVal);
    28.           //SetTagDouble(strTag,dVal);
    29.           printf("%s Value: %lf pTmp: %s  strValue: %s  Value2: %lf \r\n", strTag, dVal, pTmp, strValue, dVal2);
    30.  
    31. printf("------------------------------------------Zeile: %d--------------------------------------------\n", i);
    32.      
    33.      fclose(fpFile);
    34.  
    35. else{
    36. printf("Error: File not found!\n");
    37. }
    38.  
    39. return 0;
    40. }
    Folgende Fehlermeldungen beim Compiling:
    line 18: error (003f) : undefined identifier 'setlocale'
    line 18: error (003f) : undefined identifier 'LC_NUMERIC'
    line 18: error (0066) : 'setlocale' is not a function
    line 23: error (0066) : 'setlocale' is not a function
    line 35: error (0040) : <ident> expected before 'else'
     
  17. cwriter

    cwriter Erfahrenes Mitglied

    Naja. Du hast ja auch einen Wert "zu viel": "1.2;1,1" ist ein unbequemes Datenformat.

    Code (C):
    1. #include <locale.h>
    Partizip. Du musst die Werte nicht mehr einlesen, wohl doch aber verarbeiten, oder? Strvalue solltest du auch nicht verwenden... Wenn du den Code ein bisschen aufräumst, sollte es klarer werden.

    strtok() ist nicht threadsafe. Aber generell würde strtok einiges vereinfachen, ja. Du kannst es aber auch selbst threadsafe machen (siehe strtok_s() von Microsoft).
    Ich habe aber ein Beispiel für strchr und nicht strtok gegeben.

    Gewissermassen. Dann kannst du aber auch gleich *scanf() verwenden, was ein bisschen schöner (und mit Posix-Erweiterungen ("Halbstandard") sogar um einiges mächtiger) ist.

    Gruss
    cwriter
     
    M0zart gefällt das.
  18. M0zart

    M0zart Grünschnabel

    Vielen Dank cwriter, bin schon sehr weit gekommen
    Mein Code sieht wie folgt aus:
    Code (C):
    1. #include "apdefap.h"
    2.  
    3. int gscAction( void )
    4. {
    5. #define MaxLineLength 80
    6. FILE *fpFile;
    7. char *strTag, *strValue, *pTmp;
    8. char buffer[MaxLineLength];
    9. char delimiter[]=";";
    10. double dVal, dVal2, dVal3;
    11. int i=0, j=0;
    12. fpFile = fopen("C:\\Users\\18.01.2017 12_15.csv","r");
    13. printf("C-Skript: lese Datei: Mappe1.csv\n");
    14. if(fpFile !=NULL)
    15. {
    16.      while(fgets(buffer,MaxLineLength, fpFile))
    17.      {
    18.        
    19.           strTag=buffer;
    20. printf("strTag1: %s   Buffer: %s\n", strTag, buffer);
    21. pTmp = strtok(strTag, delimiter);
    22. printf("strTag2: %s    pTmp1: %s\n", strTag, pTmp);
    23.  
    24. //printf("dVal: %lf\n", dVal);
    25. while(pTmp != NULL) {
    26. i++;
    27. printf("strTag3: %s      pTmp2: %s\n", strTag, pTmp);
    28. dVal=atof(pTmp);
    29. printf("dVal: %lf\n", dVal);
    30. if(i==2)
    31. {dVal2=dVal;}
    32. if(i==3)
    33. {dVal3=dVal;}
    34.  
    35. SetTagDouble("wert4", dVal2); //Wert rausschreiben
    36. SetTagDouble("wert5", dVal3); //Wert rausschreiben
    37.  
    38. //nächsten Abschnitt erstellen
    39. pTmp=strtok(NULL, delimiter);
    40. printf("strTag4. %s      pTmp3: %s\n", strTag, pTmp);
    41. //printf("dVal3: %lf\n", dVal3);
    42. }
    43. j++;
    44.  
    45. printf("------------------------------------------Zeile: %d     %d--------------------------------------------\n", i, j);
    46.      }
    47.      fclose(fpFile);
    48. } else{
    49. printf("Error: File not found!\n");
    50. }
    51. return 0;
    52.  
    53. }
    Meine Ausgabe ist auch im Anhang zu sehen.
    Also ich bekomm jetzt die einzelnen Werte raus gelesen, funktioniert alles wunderbar. Muss dann nur noch irgendwas finden wie ich die Werte rausschreibe die ich brauche (Werte aus zweiter Zeile und Wert aus letzter Zeile). Aber das bekomm ich schon hin, das wird nicht das Problem sein.

    Jetzt hab ich nur noch ein Problem. Wenn ich die csv Datei in Excel öffne, hab ich zwei Varianten einmal:
    Spalte1;Zeile1: wert1
    Spalte2;Zeile1: wert2
    Spalte3;Zeile1: wert3
    Spalte1;Zeile2: wert4
    Spalte2;Zeile2: wert5
    Spalte3;Zeile2: wert6
    Bei dieser Variante funktioniert das C-Skript.

    Zweite Variante:
    Spalte1;Zeile1: wert1;wert2;wert3
    Spalte1;Zeile2: wert4;wert5;wert6
    Spalte1;Zeile3: wert7;wert8;wert9

    Bei dieser Variante funktioniert das Skript nicht. Ich muss erst die Datei in Excel öffnen und ';' als Trennzeichen eintragen, damit er die Felder trennt und neu speichern. Erst dann wird die Datei von dem Skript richtig verarbeitet. Da gibts doch sicher eine elegantere Lösung oder?
     

    Anhänge:

  19. M0zart

    M0zart Grünschnabel

    Das Problem hat sich auch erledigt :D haha. Ich muss einfach die csv Datei als UTF-8 Dateiformat speichern, dann klappt alles wunderbar.
    vielen Dank nochmal für die hilfe
     
Die Seite wird geladen...