CSV Datei Einlesen und bearbeiten



  • Hallo habe folgendes Problem.
    Nach dem einlesen der Datei möchte ich nun eine Zahl Suchen.
    Dies funktioniert jedoch nicht.
    Im Beispiel unten ist im Feld 22/2 der Wert 555.917.
    Wen ich Feld 22/2 anzeige sehe ich diesen wert auch.
    Aber die If Fiktion geht nicht.

    Sieht jemand den Fehler?

    #include <iostream>
    #include <sstream>
    #include <fstream>
    #include <vector>
    #include <string>

    using namespace std;

    int main()
    {
    float f[200][200];//feld
    float t; //zwischenspeichervariabel
    int i = 0;

    ifstream inFile("OVC.csv"); //datei öffnen
    string line; //zeilen als string behandeln
    int linenum = 0; //zeilennummer 
    while (getline(inFile, line)) //jede zeile abfragen
    {
        linenum++; //zeile auf 1 erhöhen um besser zählen zu können
        //cout << "\nLine #" << linenum << ":" << endl; //zeilennummer ausgeben
        istringstream linestream(line); //irgendwaswandeln
        string item; //item anlegen vorerst als string
    
        int itemnum = 0; //itemnummer speichern
        while (getline(linestream, item, ';')) //jedezeile durchsuchen nach trennzeichen und gefunden im item speichern
        {
    
            itemnum++; //itemnummer hochzählen 
    
            //cout << "Item #" << itemnum << ": " << item << endl; //ausgabe
            stringstream sstr; //für umwandlung
            sstr << item; //item als string in den stream schicken
            sstr >> t; //stream in float umwandeln
            f[linenum][itemnum] = t; //imfeld speichern
            
        }
    }
    cout << f[22][2];
    if (f[22][2] == 555.917)
    {
        cout << "ok";
    
    }
    system("PAUSE");
    return 0;
    

    }



  • Vergleiche Fließkommazahlen nie mit ==.

    Deine Variable t ist ein float, aber 555.917 ist ein double. Der Wert 555.917 kann weder in float noch in double exakt dargestellt werden. Auf jeden Fall sind 555.917f und 555.917 unterschiedlich.

    Stattdessen vergleiche floats, indem du sie z.B. subtrahierst und vergleichst, ob sie von nahe 0 sind, also z.B. if (abs(f[22][2] - 515.917) < 1e-5).



  • Das kann man nicht sehen, weil wir den Inhalt der CSV Datei nicht kennen. Erste Vermutung: In der CSV Datei sind die Zahlen deutsch (mit Komma) formatiert.

    Ansonsten:
    Das, was wob sagt.



  • Du kannst statt floatbesser double nehmen.
    floatkann man für sehr große Arrays nehmen um Speicherplatz zu sparen (dein Array hat gerade mal 160 kByte - bis vor 20 Jahren noch problematisch)
    Rechnen sollte man aber in double

    Oder du schreibst 555.917f . Das f am Ende zwingt den Compiler zu einem `float
    Das wird hier funktionieren, wenn in der CSV-Datei auch 555.917 steht.
    Sofern du aber damit Berechnungen anstellst, kommen Rundungsfehler dazu und das == wird nicht unbedingt funktionieren.

    @wob sagte in CSV Datei Einlesen und bearbeiten:

    Stattdessen vergleiche floats, indem du sie z.B. subtrahierst und vergleichst, ob sie von nahe 0 sind, also z.B. if (abs(f[22][2] - 515.917) < 1e-5).

    Der Schwellwert ( hier 1e-5) wird meist als Epsilon bezeichnet. Der Betrag hängt auch von der Größe der Vergleichswerte ab, muss also die Situation angepasst werden.



  • @Dabru sagte in CSV Datei Einlesen und bearbeiten:

    linenum++; //zeile auf 1 erhöhen um besser zählen zu können

    Was soll das bedeuten? Insbesondere der Kommentar im Vergleich zu dem, was tatsächlich passiert?



  • Danke, ihr seit ja schnell.

    Hab es jetzt meine float im Array auf douple geändert.
    Nun funktioniert es super.
    Der Hinweis if (abs(f[22][2] - 515.917) < 1e-5) war auch gold wert.



  • @Dabru sagte in CSV Datei Einlesen und bearbeiten:

    Der Hinweis if (abs(f[22][2] - 515.917) < 1e-5) war auch gold wert.

    Das Ding nennt sich "Epsilon-Umgebung" und empfiehlt sich in der Programmierung generell immer dann, wenn man zwei Gleitkomma-Zahlen auf Gleichheit prüfen möchte.



  • Man sollte jedoch im allgemeinen Fall absolute Epsilon-Werte vermeiden und besser relative Vergleiche benutzen, s. z.B. The Floating-Point Guide: Comparison.



  • @Th69 sagte in CSV Datei Einlesen und bearbeiten:

    Man sollte jedoch im allgemeinen Fall absolute Epsilon-Werte vermeiden und besser relative Vergleiche benutzen

    Hm. Ich weiß nicht, ob ich dem zustimmen kann. Normalerweise weiß man doch, in was für einer Größenordnung man Werte erwartet. Und dann ist ein absoluter Vergleich oft am einfachsten (und auch korrekt). Der relative Vergleich hat natürlich auch seine Berechtigung, das will ich gar nicht abstreiten - aber nur dann, wenn man nichts über die Werte weiß (das kommt bei mir selten vor). Hier weiß ich, dass es um 555.917 geht. Mit absolutem Vergleich kann ich nun viel leichter festlegen, ab welcher Zahl ich das als gleich behandeln will.


Log in to reply