Probleme mit Positionierung und Einlesen/Schreiben



  • Hallo,

    als erstes möchte ich sagen ich bin ein C-noob. Ich sitze seit Montag morgen vor meinem Rechner, bin total am verzweifeln und versuche ein Programm zu schreiben, welches Werte aus folgender Textdatei (Auszug: es handlt sich um die FETT gedruckten Werte) Werte ausliest, diese dann in eine Formel einfügt und den resultierenden Wert in eine neue (Text)Datei einfügt.

    Zyklische Erfassung Spitzenwertmessung_-1820N Zeit: 18,078613 Sec 22.01.2003 19:00:38
    Gespeichert bei: 200 Zyklus Gespeichert für: 3 Segmente
    Punkte: 2
    Zeit Vertikal Weg Vertikal Kraft
    Sec mm N
    11,550537 -0,073262166 -2303,3469
    11,588135 0,09793396 -234,5567

    [...] es geht hier so noch 3000 Zeilen lang so weiter. Immer wieder das gleiche Muster.

    Hier mein Quelltext wie weit ich bin (Ist aber in C und nicht C++)

    #include <stdio.h>
    #include <stdlib.h>
    
    main()
    {
    	FILE *quelle, *ziel;
    	char name_q[255], name_z[255];
    	int c;
    
    	long pos = 0;
    	printf("Name Quelldatei : ");
        scanf("%s",name_q);
        quelle=fopen(name_q,"r");
    
    	printf("Name Zieldatei : ");
        scanf("%s",name_z);
        ziel=fopen(name_z,"w");
    
    	fscanf(quelle,"%f",&c);
    	fprintf(ziel,"%f",&c);
    }
    
    	printf("\nAnzahl der Stellen einrücken (vom Anfang): ");
    	scanf("%ld",&pos);
    	fflush(stdin);
    
    	fseek(quelle, 0L, SEEK_SET);
    
    	while( (c=getc(quelle)) != EOF)
    	{
    		putc(c,ziel);
    		putc(c,stdout);
    
    		fseek(quelle, pos, SEEK_CUR);
    
    	}
    }
    

    mein Problem ist folgendes:
    Ich komm nicht drauf, wie ich in der geöffneten Datei an eine bestimmte Position gelange (so weit bin ich ja schon mit SEEK) UND eine der fettgedruckten Zahlen entnehme um sie danach (zwischendrin müsste sie ja noch in eine simple Formel eingesetzt werden) in eine andere Textdatei zu schreiben. Einzelne Zeichen kann ich ja mit
    "fgetc"
    entnehmen, aber eine Zeichenkette?
    Das ganze könnte man doch in eine Schleife setzen (welche mit EOF abbricht) um alle Werte zu entnehmen?

    Könnt ihr mir evtl. Tipps/Anregungen geben mit was ich das machen könnte?
    Freue mich über jegliche Hilfestellung/links etc etc.

    Vielen dank im voraus!

    Grüße



  • Hallo,

    habe gemerkt, dass ich euch einen falschen Quelltext gegeben habe. Tut mir Leid. Da wollt eich was hinzufügen und war totaler Schrott.

    😞

    Hier der "richtige"

    #include <stdio.h>
    #include <stdlib.h>
    
    main()
    {
    	FILE *quelle, *ziel;
    	char name_q[255], name_z[255];
    	int c;
    
    	long pos = 0;
    	printf("Name Quelldatei : ");
        scanf("%s",name_q);
        quelle=fopen(name_q,"r");
    
    	printf("Name Zieldatei : ");
        scanf("%s",name_z);
        ziel=fopen(name_z,"w");
    
    	printf("\nAnzahl der Stellen einrücken (vom Anfang): ");
    	scanf("%ld",&pos);
    	fflush(stdin);
    
    	fseek(quelle, 0L, SEEK_SET);
    
    	while( (c=getc(quelle)) != EOF)
    	{
    		putc(c,ziel);
    		putc(c,stdout);
    
    		fseek(quelle, pos, SEEK_CUR);
    
    	}
    }
    


  • hm...nimm doch c++ oder anderes forum!

    wenn c++ dann: fstream anschauen!
    string anschauen!

    tip-> alles in string lesen, und da bearbeiten!



  • Hallo,

    hier der aktuelle gesamte Quelltext:

    #include <fstream>
    #include <iostream>
    #include <sstream>
    #include <string>
    #include <cmath>
    
    using namespace std;
    
    int main(int argc, char* argv[])
    {
        string strFileIn, strFileOut;
        string strLine, strTest;
        double d1, d2, d3, d4, d5, d6, dOut, dQuo, c0 = 11926.309;
    	double dx;
    	double c1, c2, c3, c4;
        int iLineCount = 0, iBlockCount = 0;
    
        //argumente prüfen
        if (argc < 3)
        {
            //keine oder zuwenig Parameter angegeben -> nach den Dateinamen fragen
            cout << "Eingabedatei angeben: ";
            cin >> strFileIn;
            cout << endl;
            cout << "Ausgabedatei angeben: ";
            cin >> strFileOut;
            cout << endl;
        }
        else
        {
            //Dateinamen aus Parameter-Array übernehmen
            strFileIn = argv[1];
            strFileOut = argv[2];
        }
    
        //Dateien öffnen
        ifstream in(strFileIn.c_str());
        if(!in) return -2;
        ofstream out(strFileOut.c_str());
        if(!out) return -3;
    
        //Datei lesen
        do
        {
            //Zeile einlesen
            getline(in, strLine);
            //alles OK?
            if(in)
            {
                //alles OK, kein Fehler aufgetreten und Datei noch nicht zu Ende
                //string in stringstream kopieren
                stringstream ssLine(strLine);
                ssLine >> strTest;
                //Wenn das 1. Wort 'Zyklische' ist, Zeilenzähler zurücksetzen und Blockzähler erhöhen
                if(strTest == "Zyklische")
                {
                    iLineCount = 0;
                    iBlockCount++;
                }
    
                //Zeile zählen
                iLineCount++;
                //Wenn Zeile leer ist, nichts machen
                if(strLine.empty())
                    continue;
    
    			if(iLineCount == 2 && iBlockCount > 0)
                {
                    //für 2. Zeile
                    //string in stringstream kopieren
                    stringstream ssLine(strLine);
    				ssLine >> strTest;
                    //Zeichenketten aus stringstream auslesen
                    ssLine >> c1 >> c2 >> c3 >> c4 >> dx >> c6 >> c7 >> c8;
    				out << "Block " << iBlockCount << " bei Lastwechsel " << dx << endl;
    			}
    
                if(iLineCount == 6 && iBlockCount > 0)
                {
                    //für 6. Zeile
                    //Kommata durch Punkte ersetzen
                    for(string::iterator itStr = strLine.begin(); itStr != strLine.end(); itStr++)
                        if((*itStr) == ',') (*itStr = '.');
                    //string in stringstream kopieren
                    stringstream ssLine(strLine);
                    //Zahlen aus stringstream auslesen
                    ssLine >> d1 >> d2 >> d3;
                }
    
    			if(iLineCount == 7 && iBlockCount > 0)
                {
                    //ab 7. Zeile
                    //Kommata durch Punkte ersetzen
                    for(string::iterator itStr = strLine.begin(); itStr != strLine.end(); itStr++)
                        if((*itStr) == ',') (*itStr = '.');
                    //string in stringstream kopieren
                    stringstream ssLine(strLine);
                    //Zahlen aus stringstream auslesen
                    ssLine >> d4 >> d5 >> d6;
                    //Berechnung durchführen
                    dOut = ((d6 + fabs(d3)) / (fabs(d2) + d5));
    				dQuo = (dOut / c0);
                    //Genauigkeit der Ausgabe setzen
                    out.precision(10);
                    //Ergebnis ausgeben
                    out << dOut << endl;
    		out << dQuo << endl;
    	            }
            }
        //bis Dateiende oder Fehler
        }while(in);
    
        return 0;
    }
    

    Also die Rechenoperationen stimmen. Die Ergebnisse sind richtig. Wäre es noch möglich die Bearbeitung von Zeile 6. und 7. "eleganter" darzustellen (Eher unwichtig)?

    Hier

    if(iLineCount == 2 && iBlockCount > 0)
                {
                    //für 2. Zeile
                    //string in stringstream kopieren
                    stringstream ssLine(strLine);
    				ssLine >> strTest;
                    //Zeichenketten aus stringstream auslesen
                    ssLine >> c1 >> c2 >> c3 >> c4 >> dx >> c6 >> c7 >> c8;
    				out << "Block " << iBlockCount << " bei Lastwechsel " << dx << endl;
    }
    

    versuche ich die Lastwechsel, also die hier fettgedruckte Zahl aufzunehemn da sie auschlaggebend ist. Mein Problem ist, dass ich beim einlesen der zeile zuerst das erste Wort(Zeichenkette) einlese und danach nur einzelne Zeichen.
    In C gibt es ja einen Unterschied zwsichen char *c (einzelne Zeichen) und char *s (Zeichenkette bis tab, leerzeile, linefeed etc). Wie it das in C++?

    Zyklische Erfassung Spitzenwertmessung_-1820N Zeit: 18,078613 Sec 22.01.2003 19:00:38
    Gespeichert bei: 200 Zyklus Gespeichert für: 3 Segmente
    Punkte: 2
    Zeit Vertikal Weg Vertikal Kraft
    Sec mm N
    11,550537 -0,073262166 -2303,3469
    11,588135 0,09793396 -234,5567

    Auch hätte ich gern anfangs eine Abfrage, ab welchen Lastwechsel die Berechnung starten und bei welchem sie enden soll. In diesem Beispiel erhöht sich die Zahll um jeweils 100 pro "Absatz". Die Realisierung fällt mir sehr schwer.

    Nun ich möchte das Ergebnis evtl. in Excel vorliegen haben, also würde ich es als .csv Datei absepeichern.

    Nun müssten "Anzahl der Lastwechsel bzw. Blocknummer", "dOut" und "dQuo" nebeneinander in Excel stehen, damit man mit den daten einfach weiterarbeiten kann.

    Ich habe es folgendermasßen versucht jedoch wird das Ergebnis totaler Schwachsinn:

    out << "Block " << iBlockCount << " bei Lastwechsel " << dx << ";" << dOut << ";" << dQuo << endl;
    

    Hat jemand eine Idee wie ich diese Probleme lösen kann?

    Danke für eure Antworten im voraus.

    Grüße



  • Hallo, das problem mit der csv Datei hat sich erledigt. Es lag an der loakalen Einstellung von Excel. Habe das jetzt geändert und es klappt wunderbar.

    Jedoch komme ich nicht darauf, woran es liegt, dass beim einlesen (folgender Quelltext) an "fünfter" Stelle die gesuchte Zahl (in Antwort davoir fett gedruckt) liegt?

    Wo ist der Fehler im Code?

    Müsste imho doch an 3. Stelle liegen.

    Also:

    1.Stelle: "Gespeichert" // 2. Stelle: "bei:" // 3. Stelle (das was ich will): "200"

    Kann mir jemand weiterhelfen?

    if(iLineCount == 2 && iBlockCount > 0)
                {
                    //für 2. Zeile
                    //string in stringstream kopieren
                    stringstream ssLine(strLine);
    				ssLine >> strTest;
                    //Zeichenketten aus stringstream auslesen
                    ssLine >> c1 >> c2 >> c3 >> c4 >> dx >> c6 >> c7 >> c8;
    				out << "Block " << iBlockCount << " bei Lastwechsel " << dx << endl;
    }
    

Anmelden zum Antworten