[c++]Einlesen von werten aus datei und in char oder int überegebn

guddy

Mitglied
Hallo Leute,

Ich habe folgende Inputdatei:

Code:
Anzahl der Variablen:3

Var_nr;uGrenze;oGrenze
1;5;50
2;44;450
3;55;500

Mit folgendem Code wurde die Anzahl der Variablen als wert eingelesen und alles was unter Var_nr..... steht in einen vector gepackt:



C++:
#include <iostream>
#include <fstream>
#include <vector>
#include <limits>

template< char C >
std::istream& Char( std::istream& in )
{
    char c;
    if( in >> c && c != C )
        in.setstate( std::ios_base::failbit );
    return in;
}

struct Foo
{
    int m_var, m_uGrenze, m_oGrenze;
    	
};

std::istream& operator>>( std::istream& in, Foo& x ) //formatierter input (was bedeuten die Werte in den Klammern? in=Name des iputstream und Ausgabe in x
{
    return in >> x.m_var >> Char<';'> >> x.m_uGrenze >> Char<';'> >> x.m_oGrenze; //gibt Werte des inputstream in zurück aber ohne ";"? und zwar in die Variablen der Strucktur x?
}

std::istream& read3DArray( std::istream& in, std::vector< Foo >& dreiD_ ) //Definier von istream abgeleitete Funktion read3DArray mit inputstreamquelle  in und Ziel vector dreiD_ mit daten-bzw. structurtyp Foo 
{
    
    in.ignore( std::numeric_limits< std::streamsize >::max(), ':' ); // ignore(streamlänge, Zeichen) ignoriert Strom bis zu dem Punkt, wenn Streamlänge erreicht oder Zeichen gefunden
    
    std::size_t anzahl; //size_t übergibt Wert oder stringlänge von Anz_Var an Variable anzahl?
    char dummy; // das Lesen des 'dummy' garantiert, das sich der Lesezeiger in der Kommenatrzeile befindet 
    if( (in >> anzahl >> dummy)
            .ignore( std::numeric_limits< std::streamsize >::max(), '\n' ) ) // Kommentar überlesen
    {
        std::vector< Foo > dreiD; //erzeugt Vektor mit datentyp/Structur Foo mit namen dreiD?
        dreiD.reserve( anzahl );    // optional, reserviert ein Minimum an Speicher von anzahl für den Vector dreiD 
        for( Foo x; anzahl && in >> x; --anzahl ) //Führe aus (Structur x; ?; Zähle anzahl runter 
            dreiD.push_back( x );//fülle Vektor dreiD mit x vom Structurtyp foo
        if( in ) // wenn in != o dann 
            swap( dreiD, dreiD_ );  // ok; dann übernehmen,   swap tauscht Werte von Object dreiD zu dreiD_ , Warum?
    }
    return in; //gib in zurück, warum?
}

int main()
{
    using namespace std;
    vector< Foo > dreiD;
    char prozessname[256]; 	
    ifstream file( "Variableninput.dat" );
    if( !file.is_open() )
    {
        cerr << "Fehler beim Oeffnen der Datei Variableninput" << endl;
        return -1;
    }
    if( read3DArray( file, dreiD, prozessname) )
    {
        cout << "Vector eingelesen" << endl;
	cout << dreiD[1].m_var << endl;;
    }
}

Nun möchte ich die Inputdatei wie folgt erweitern:

Code:
Prozessname: Rankine
Datum oder Zifferncodierung: 66
GA-Typ: 1
Genome-Typ: 2
Testfunktionstyp: 1
Anzahl der Durchläufe: 100
Anzahl der Variablen:3

Var_nr;uGrenze;oGrenze
1;5;50
2;44;450
3;55;500

Wie kann ich den Code abändern um die Werte nach ":" als char (bei Prozessname, Datum oder Ziffern) und als int (bei GA-Typ, testfunktion und Anzahl der durchläufe) abzuspeichern?


Danke für eure Hilfe.

Grüße

Guddy
 
Machst du dir das nicht ein wenig zu kompliziert?
Lies doch einfach die gesamte Datei zeilenweise in ein array von strings.
Solange die Anzahl Zeilen immer gleich ist hast du danach schon alles was du brauchst, um jede beliebige Zeile einzeln anzusprechen oder mit einem einfachen loop durchs array die Zeilen nacheinander zu bearbeiten, wobei loop (0 - x) = char und loop (x - ende) = int

Selbst wenn die Anzahl Zeilen immer verschieden ist, brauchst du nur sowas wie eine Trennzeile einzufügen, alles davor als string und alles danach als int behandeln.
Auch querbeet char und int gemischt würde gehen, wenn du jeder Zeile eine 0 oder 1 voran stellst, die angibt, ob es eine char oder eine int Zeile sein soll.
 
Hey,

ich möchte möglichts den obigen Code verwenden. Das funktioniert einwandfrei, außerdem wir es sonst unübersichtlich. Die Anzahl der Variablen wurde ja schon eingelesen. Nun soll die Funktion um die anderen einträge ergänzt werden. Leider mach ich da irgendwas falsch...
 
Was für nen Schwachsin von wegen Zeilenweise erst einlesen usw.. So ist es wesentlich sauberer gelöst! Respekt für diese Lösung!

C++:
std::vector< Foo > dreiD(anzahl);
std::copy(std::istream_iterator<Foo>(in), std::istream_iterator<Foo>(), dreiD);

if (in) std::swap( dreiD, dreiD_ );
wäre aber eleganter, als deine Zeile 36 bis 41 :P

Soll man dir die "warum?"-Fragen noch beantworten? ;)

Kleine Fehler in der main-Funktion:
- main gibt entweder 0 oder 1, nicht aber -1 zurück.
- Variablen erst anlegen, wo sie gebraucht werden.

C++:
int main()
{
    using namespace std;
    
    ifstream file_stream("Variableninput.dat");
    if (!file_stream)
    {
        cerr << "FEHLER: Die Datei \"Variableninput.dat\" konnte nicht geöffnet werden!" << endl;
        return 1;
    }

    std::vector<Foo> data;
    if (!read3DArray(file_stream, data) ) 
    {
        cerr << "FEHLER: Die Datei \"Variableninput.dat\" ist ungültig!" << endl;
        return 1;
    }
    
    cout << "Daten erfolgreich eingelesen!\n";
           << data.at(1).m_var;
}
...
 
Hey,

und wie ändere ich das ganze nun, so dass die anderen Zeilen auch als int bzw. char(siehe oben) eingelesen werden?

Grüße

Guddy
 
Zurück