2 Stimmen

Lesen von Teilen einer Eingabedatei

Ich möchte eine Eingabedatei in C++ lesen, deren Struktur (oder das Fehlen einer solchen) in etwa aus einer Reihe von Zeilen mit Text = Zahl , wie zum Beispiel

input1 = 10
input2 = 4
set1 = 1.2
set2 = 1.e3

Ich möchte die Nummer aus der Zeile nehmen und den Rest wegwerfen. Zahlen können entweder ganze Zahlen oder Doppelzahlen sein, aber ich weiß, wann sie das eine oder das andere sind.

Ich würde es auch gerne lesen, wie

input1 =    10
input2=4
set1   =1.2
set2= 1.e3

um für den Benutzer robuster zu sein. Ich denke, das bedeutet, dass sie nicht in formatierter Form rot sein sollte.

Wie auch immer, gibt es eine intelligente Möglichkeit, das zu tun?

Ich habe bereits das Folgende versucht, aber mit minimalen Kenntnissen über das, was ich getan habe, so dass das Ergebnis wie erwartet war... kein Erfolg.

    #include <stdio.h>
    #include <stdlib.h>
    #include <float.h>
    #include <math.h>
    #include <iostream>
    #include <fstream>
    #include <iomanip>
    #include <cstdlib>
    #include <boost/lexical_cast.hpp>
    #include <string>

    using namespace std;
    using namespace boost;

    int main(){

            string tmp;
            char temp[100];

            int i,j,k;

            ifstream InFile("input.dat");

            //strtol
            InFile.getline(temp,100);
            k=strtol(temp,0,10);
            cout << k << endl;

            //lexical_cast
            InFile.getline(temp,100);
            j = lexical_cast<int>(temp);
            cout << j << endl;

            //Direct read
            InFile >> tmp >> i;
            cout << i << endl;

            return 0;
    }

6voto

Martin York Punkte 245363

Lesen Sie einfach eine Zeile nach der anderen.
Trennen Sie dann jede Zeile durch das '='-Zeichen. Verwenden Sie die Stream-Funktionalität für den Rest.

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

int main()
{
    std::ifstream    data("input.dat");
    std::string      line;

    while(std::getline(data,line))
    {
        std::stringstream    str(line);
        std::string          text;

        std::getline(str,text,'=');

        double   value;
        str >> value;
    }
}

Mit Fehlerprüfung:

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

int main()
{
    std::ifstream    data("input.dat");
    std::string      line;

    while(std::getline(data,line))
    {
        std::stringstream    str(line);
        std::string          text;
        double               value;

        if ((std::getline(str,text,'=')) &&  (str >> value))
        {
            // Happy Days..
            // Do processing.
            continue; // To start next iteration of loop.
        }
        // If we get here. An error occurred.
        // By doing nothing the line will be ignored.
        // Maybe just log an error.
    }
}

5voto

MattyT Punkte 6206

Hier gibt es bereits einige gute Lösungen. Um es jedoch gleich vorwegzunehmen: In einigen Kommentaren wurde angedeutet, dass Boost Spirit eine ungeeignete Lösung für dieses Problem ist. Ich bin mir nicht sicher, ob ich da völlig anderer Meinung bin. Die folgende Lösung ist jedoch sehr knapp und gut lesbar ( wenn Sie kennen EBNF) und fehlertolerant. Ich würde es in Betracht ziehen, es zu verwenden.

#include <fstream>
#include <string>
#include <boost/spirit.hpp>

using namespace std;
using namespace boost::spirit;

int main()
{
    ifstream       data("input.dat");
    string         line;
    vector<double> numbers;

    while(getline(data,line))
    {
        parse(line.c_str(), 
            *(+~ch_p('=') >> ch_p('=') >> real_p[push_back_a(numbers)]), 
            space_p);
    }
}

2voto

Bklyn Punkte 2542

C FTW (modifiziert, um Doppelgänger zu behandeln)

#include <stdio.h>

int
main ()
{
    double num;

    while (!feof (stdin))
         if (1 == fscanf (stdin, "%*[^=] = %lf", &num))
            printf ("%g\n", num);

    return 0;
}

2voto

Dunya Degirmenci Punkte 412

Verstehe ich das richtig? Du nimmst die Zeile, extrahierst die Zahl daraus und druckst sie aus (oder verwendest sie woanders, was auch immer)? Wenn ja, können Sie die String-Funktionen und istringstream verwenden:

//these are your codes, removing some though
#include <stdio.h>
#include <stdlib.h>
#include <float.h>
#include <math.h>
#include <iostream>
#include <fstream>
#include <string>
//adding
#include <sstream>

using namespace std;

int main()
{
string line="", extract="";
int placeofop=0, input;
ifstream InFile("input.dat");

while(!InFile.eof())
{
     getline(InFile, line);
     placeofop = line.find("=");
     extract = line.substr(placeofop, (line.length()-placeofop));
     istringstream trythis(extract);
     trythis >> input;
     cout << input << endl;
}

return 0;
}  

Ich bin mir nicht 100%ig sicher, ob ich mich an die Funktionen richtig erinnere, aber es sollte funktionieren, wenn ich sie alle richtig verstanden habe.

edit: Ich habe gemerkt, dass ich meine Beiträge bearbeiten kann :) Ich habe die <<'s und >>'s wie im Kommentar vertauscht; etwas, das ich immer wieder mache... Jetzt gibt es keine Kompilierungsfehler mehr.

2voto

Frank Krueger Punkte 67044

Aus dem Stegreif:

vector<double> vals(istream &in) {
    vector<double> r;
    string line;

    while (getline(f, line)) {
        const size_t eq = line.find('=');
        if (eq != string::npos) {
            istringstream ss(line.substr(eq + 1));
            double d = 0;
            ss >> d;
            if (ss) r.push_back(d);
            else throw "Line contains no value";
        }
        else {
            throw "Line contains no =";
        }
    }

    return r;
}

int main(int argc, char *argv[]) {
    vector<double> vs = vals(ifstream(argv[1]));
}

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X