Textimport

_gurke_

Grünschnabel
Hallo Leute,

Ich habe neben wachsender Verzweifelung ein Texfile was Aussieht wie

PHP:
        Time / s                Port1 (1)/real
----------------------------------------------------------------------
                       0                              -0
            2.14125e-005                              -0
             2.1413e-005                  3.7058987e-005
            2.14135e-005                   0.00031992671
             2.1414e-005                   0.00042713375
            2.14145e-005                   0.00064373014
             2.1415e-005                   0.00087175442
            2.14155e-005                    0.0010936944
             2.1443e-005                     0.012777633
             2.1444e-005                     0.013188761
            2.14445e-005                     0.013388439
            ....                                     ....


usw. - es kommen mehrere Header im File vor (die Header sehen aber immer gleich aus).

Das File ist leider über 2GB groß und Matlab fühlt sich "etwas" überfordert. Daher möchte ich mit C++ die Datenmenge reduzieren.

Ich möchte die Daten einlesen und jeweils aus drei nacheinander-folgenden Datensätze das ariethmetische Mittel ausgeben (um Aliazing zu verhindern reicht es leider nicht nur jede dritte Zeile auszugeben).

Wenn ein Header kommt soll dieser 1:1 ausgegeben werden.

Ich bastel jetzt schon seit einer Ewigkeit daran rum... irgendwie bin ich einfach zu blöd dazu :-/

Bitte um eure Geduld und Hilfe :)
 
Hi _gurke und herzlich Willkommen hier im Forum.

Woran scheitert es denn? Hast du schon einen Code, den ich mir anschauen kann? So aus dem Nichts heraus ist es schwer zu sagen was falsch läuft ;)

Grüße,
BK
 
Hi,
hast du das Beispiel oben selbst formatiert für die Lesbarkeit, oder ist die Datei genau so formatiert? Hast du die Datei selbs erzeugt?
Wie genau sehen die Header aus? Immer wie du obengepostet hast mit Text, neuer Zeile und ganz vielen '-'? Immer gleichviele?
Wenn die äußeren Umstände immer gleich sind, kann man sehr schnell mit fscanf und einem gut gewählten Format-String arbeiten. Sonst müsstest du mühsam mit getline() jede Zeile auslesen und erstmal sehen ob Header oder Daten.

Grüße
 
Hi,

danke für die Antworten.

Also...:

Die Dateien werden von einem Messgerät erzeugt, die "-----" Zeichen sind immer gleich viele, beim Header ändert sich von Mal zu Mal nur die Zahl im Ausdruck "Port1 (1)/real".

Mein bisheriger Ansatz: (bitte nicht lachen)

Ich öffne die Datei (ResStromModell_7.txt) und will die Daten in reduzierter Form in die Datei (C_Ausgabe_ResStromModell_7.txt) schreiben.

Ich lese mit einer Schleife aus den Daten und lasse dabei die Variable "wichone" hochzählen. Wenn wichone zwischen 0 und 9 ist, werden die Zahlen in den Variablen Freq1-Freq5 bzw. die Signalwerte in Sig1-Sig5 gespeichert.

Wenn die Differenz der Daten kleiner ist als Minrate = 1/30000000 wird das ariethmetische Mittel gebildet, ansonsten werden die Zahlen unverändert ausgegeben. Anschließend wird wichone wieder auf 0 gesetzt, die nächsten 5 Werte werden eingelesen.

Wenn ein Header erkannt wird, wird wichone auf -20 gesetzt womit das Programm keine Daten mehr erwartet, stattdessen wird der Header ausgegeben. Sobald der Teil mit "------" gefunden wird, wird dieser ausgegeben und wichone wird wieder auf 0 gesetzt, fängt also wieder an Freq bzw. Signaldaten einzulesen.

Leider gibt das Programm völlig unsinnige Zahlenwerte aus :-(

Zumindest die Header scheinen an der richtigen Stelle zu sein****




PHP:
#include "stdafx.h"
#include <fstream>
#include <iostream>
#include <string>
#include <sstream>
#include <stdio.h>
#include <stdlib.h>               
#include "conio.h"


using namespace std;


int _tmain(int argc, _TCHAR* argv[])
{

	
	ifstream inFile;
	ofstream outFile;

	inFile.open("ResStromModell_7.txt");
	outFile.open("C_Ausgabe_ResStromModell_7.txt");

	string item;


	double Freq1 = 0;
	double Freq2 = 0;
	double Freq3 = 0;
	double Freq4 = 0;
	double Freq5 = 0;

	double Sig1;
	double Sig2;
	double Sig3;
	double Sig4;
	double Sig5;
	
	double Differenz = 0;
	double Minrate = 1/30000000;


	double itemdouble;

	int MeasurementNumber = 1;

	int count = 0;
	int wichone = 0;



	
	while (!inFile.eof()) 
	{
		inFile >> item;
		count++;
		wichone++;


		// write header

		if (item == "Time") 
		{
		outFile << "Time / s                Port1 (" << MeasurementNumber << ")/real" << endl;
		outFile << "----------------------------------------------------------------------" << endl;
		MeasurementNumber++;
		wichone = -20;
		}



		{
		if (item =="----------------------------------------------------------------------")
		wichone = -1;
		}


		//if the item is not part of the header: create a double

		if (wichone >= 0) 
		{
		inFile >> itemdouble;
		}



		// Select Frequency or Signal

		if (wichone == 0)
		{
		Freq1 =itemdouble;
		}

		if (wichone == 1)
		{
		Sig1 = itemdouble;
		}

		if (wichone == 2)
		{
		Freq2 = itemdouble;
		}

		if (wichone == 3)
		{
		Sig2 =itemdouble;
		}

		if (wichone == 4)
		{
		Sig3 =itemdouble;
		}

		if (wichone == 5)
		{
		Sig3 =itemdouble;
		}

		if (wichone == 6)
		{
		Sig4 =itemdouble;
		}

		if (wichone == 7)
		{
		Sig4 =itemdouble;
		}

		if (wichone == 8)
		{
		Sig5 =itemdouble;
		}

		if (wichone == 9)
		{
		Sig5 =itemdouble;
		}


		// Calculate middle and save data in new File

		if (wichone ==9)
		{
			Differenz = Freq5-Freq4;

			if (Freq4-Freq3 < Differenz)
				{
				Differenz = Freq4-Freq3;
				}
		
			if (Freq3-Freq2 < Differenz)
				{
				Differenz = Freq3-Freq2;
				}

			if (Freq2-Freq1 < Differenz)
				{
				Differenz = Freq2-Freq1;
				}


			if (Differenz >= Minrate) 
				{
				outFile << "          " << Freq1 << "          " <<Sig1 << endl;
				outFile << "          " << Freq2 << "          " <<Sig2 << endl;
				outFile << "          " << Freq3 << "          " <<Sig3 << endl;
				outFile << "          " << Freq4 << "          " <<Sig4 << endl;
				outFile << "          " << Freq5 << "          " <<Sig5 << endl;
				}

			if (Differenz < Minrate) 
				{
				outFile << "          " << (Freq1 + Freq2 + Freq3 + Freq4 + Freq5)/5 << "          " << (Sig1 + Sig2 + Sig3 + Sig4 +Sig5)/5 << endl;
				wichone = -1;
				}
		}
	}
	

		
	cout << count << " items found! Last Item: " << item << endl;
	
	int n ;
	cin >> n;
	
	outFile.close();
	inFile.close();

	return 0;
}
 
Hallo,

die unsinnigen Zahlen kommen möglicherweise daher, dass du eine Integer-Division durchführst. Teile deine Zahlen durch einen double Wert:
C++:
(Freq1 + Freq2 + Freq3 + Freq4 + Freq5)/5.0

Außerdem könntest du dein Programm noch etwas einfacher gestalten ;) Wenn du ein Array nutzt kannst du dir z.B. die ganzen if's sparen, z.B.
C++:
double FreqArray[10];
if(whichone >= 0 && whichone <= 9) {
	inFile >> itemdouble;
	FreqArray[whichone] << itemdouble;
}
Anschließend kannst du auf deine werte in dem Array zugreifen.
 
Hallo,

danke für die Antwort - das Teilen durch den int Wert klappt (habs ausprobiert).

Ich habe jetzt endlich :) :-D :) einen funktionsfähigen Code.

Das Problem war: ich habe zweimal auf den Strem zugegriffen, einmal um zu gucken ob ich mich im Header befinde, und dann (falls ich nicht im Header bin) ein zweites Mal um den Wert in ein double umzuwandeln. Leiter hat sich der Marker in der Textdatei hierbei eins weiter bewegt, daher die merkwürdigen Ausgaben (ein Teil der Werte wurde übersprungen).

Ich habe das Problem jetzt gelöst (bitte nicht schlagen) indem ich die Daten beim header-überprüfen in ein zweites File schreibe, das File dann wieder importiere, und dann erst ein double daraus mache.

Ich habe versucht die konvertierung string->double direkt mit einer über google gefundenen sring-stream Konvertierung zu machen, leider kam für itemdouble immer nur Eins raus.

Wisst ihr, wie man die Konvertierung ohne zweiten/dritten Festplattenzugriff umschreiben kann? Der Code wird dadurch leider sehr langsam...

Ich markiere die Stelle im Code mit "sehr schlechte Konvertierung"....

PHP:
#include "StdAfx.h"
#include <algorithm>
#include <fstream>
#include <iostream>
#include <iterator>
#include <sstream>
#include <string>
#include <vector>

 
using namespace std;
 
int main(void) 
	{

  
	int wichone = 0;
	int breakcounter;
	int MeasurementNumber =1;
	string item;
	string line;
	double itemdouble;
	
	double Freq1 = 0; 
    double Freq2 = 0; 
    double Freq3 = 0; 
    double Freq4 = 0; 
    double Freq5 = 0; 

    double Sig1; 
    double Sig2; 
    double Sig3; 
    double Sig4; 
    double Sig5; 
     
    double Differenz = 0; 
    double Minrate = 1/30000000; 



	ofstream outFile; //auslesen
	ifstream Eingabefile("ResStromModell_7.txt"); //reinschreiben
	ifstream ZwischenSpeicher;
	ifstream ZwischenSpeicher2;
	ofstream ZwischenSpeicherReinschreiben2;
	ofstream ZwischenSpeicherReinschreiben;
	outFile.open("C_Ausgabe_ResStromModell_7.txt");


  

  //---------------------------------------------------------------

  vector<vector<double> > matrix;
	while (Eingabefile) 
		{

		
		getline(Eingabefile, line);

		//outFile <<  line << endl;

		ZwischenSpeicherReinschreiben.open("ZW.txt");
		ZwischenSpeicherReinschreiben << line << endl;
		ZwischenSpeicherReinschreiben.close();

		breakcounter = 1;

		ZwischenSpeicher.open("ZW.txt");
		
		
		while (!ZwischenSpeicher.eof())
			{
				ZwischenSpeicher >> item; 
				wichone++;

				//outFile << "Zahlfound:" <<item << endl;

				if (item == "Time")
					{
						outFile << "Time / s                Port1 (" << MeasurementNumber << ")/real" << endl;
						outFile << "----------------------------------------------------------------------" << endl;
						MeasurementNumber++;
						wichone = -20;
					}

				if (item == "----------------------------------------------------------------------")
					{
						wichone = -1;
					}

				//if the item is not part of the header: create a double 

				if (wichone >= 0)  
					 { 
//"sehr schlechte Konvertierung"
							ZwischenSpeicherReinschreiben2.open("ZW2.txt");
							ZwischenSpeicherReinschreiben2 << item << endl;
							ZwischenSpeicherReinschreiben2.close();

							ZwischenSpeicher2.open("ZW2.txt");
							ZwischenSpeicher2 >> itemdouble;
							ZwischenSpeicher2.close();
					 
} 



				// Select Frequency or Signal 

				if (wichone == 0) 
					{ 
						Freq1 =itemdouble; 
					} 

		        if (wichone == 1) 
					{ 
						Sig1 = itemdouble; 
					} 

				if (wichone == 2) 
					{ 
						Freq2 = itemdouble; 
					} 

				if (wichone == 3) 
					{ 
						Sig2 =itemdouble; 
					} 

				if (wichone == 4) 
					{ 
						Freq3 =itemdouble; 
					} 

				if (wichone == 5) 
					{ 
						Sig3 =itemdouble; 
					} 

				if (wichone == 6) 
					{ 
						Freq4 =itemdouble; 
					} 

				if (wichone == 7) 
					{ 
						Sig4 =itemdouble; 
					} 

				if (wichone == 8) 
					{ 
						Freq5 =itemdouble; 
					} 
		
				if (wichone == 9) 
					{ 
						Sig5 =itemdouble; 
					} 


				// Calculate middle and save data in new File 

				if (wichone ==9) 
				{
						outFile << "          " << (Freq1 + Freq2 + Freq3 + Freq4 + Freq5)/5 << "          " << (Sig1 + Sig2 + Sig3 + Sig4 +Sig5)/5 << endl;
						wichone = -1; 

					}

				// Wenn Ende des eingelesenen Strings (eine Zeile des Files) erreicht ist, bricht die while Schleife ab
				breakcounter = breakcounter +1;
				
				if (breakcounter ==3)
					{
						break;
					}

			}

		ZwischenSpeicher.close();

	}
 




 
  outFile.close();

  getchar;

  return 0;
}
 
Zuletzt bearbeitet:
Nochmal separat der sehr langsame und unsaubere Teil mit dem doppelten HDD-Zugriff (ca in der Mitte vom Quelltext):

item = string
itemdouble = double

PHP:
//"sehr schlechte Konvertierung" 
                            ZwischenSpeicherReinschreiben2.open("ZW2.txt"); 
                            ZwischenSpeicherReinschreiben2 << item << endl; 
                            ZwischenSpeicherReinschreiben2.close(); 

                            ZwischenSpeicher2.open("ZW2.txt"); 
                            ZwischenSpeicher2 >> itemdouble; 
                            ZwischenSpeicher2.close();

Kann das jemand intelligenter ohne HDD-Zugriff formulieren?
 
Hi Jennesta,

ich habs mir angesehen: leider komme ich nicht von selbst drauf :-/

Wenn ich eine string-Variable direkt als Zahl erstelle , wie z.B.

PHP:
str MyVar = 123.6434"

klappt die Konvertierung mit dem stringstream hervorragend.

Wenn ich dei Daten auf die eingelesenen Werte aus einem beispielhaftes Textfile anwende:
PHP:
        Time / s                Port1 (1)/real
----------------------------------------------------------------------
            1                 7  
            1.1                 7  
            1.2                 7  
            1.3                 7  
            1.4                 7  
            1.5                 7  
            7                 7  
            8                 7  
            9                 7  
            10                 7  
            11                7  
            12                 7  
            12                 7  
            12                 7
            12                 7

und dann mit Stringstream arbeite (ss = stringstream)

PHP:
ss << item;
ss >> itemdouble;
cout << "item: " << item << "itemdouble: " << itemdouble << endl;

ist die Ausgabe:

  • item: 1 itemdouble: 1
  • item: 7 itemdouble: 1
  • item: 1.1 itemdouble: 1
  • item: 7 itemdouble: 1
  • item: 1.2 itemdouble: 1

für das eingelesene item immer richtig, der konvertierte itemdouble Wert ist jedoch immer 1.

Wenn ich die Werte mit dem Befehl

PHP:
//"sehr schlechte Konvertierung" 
                            ZwischenSpeicherReinschreiben2.open("ZW2.txt"); 
                            ZwischenSpeicherReinschreiben2 << item << endl; 
                            ZwischenSpeicherReinschreiben2.close(); 

                            ZwischenSpeicher2.open("ZW2.txt"); 
                            ZwischenSpeicher2 >> itemdouble; 
                            ZwischenSpeicher2.close();

in eine exportiere und als double reimportiere, bekomme ich die richtigen Werte.

Help :-/
 
Zurück