Zum Inhalt springen

datei aus Matrix einlesen in c++


nefertari001

Empfohlene Beiträge

Hallo

ich hab einen 2 dim array angelegt, in diesem array sollen dateien abgelegt werden. jetzt bekomme ich eine Position übergeben und soll an diese Stelle im array springen und diese datei dann einlesen und anschließend damit noch weiterarbeiten.

der befehl für das einlesen wäre ja

ifstream myfile ("n38.min");

und dann mit seekg und tellg damit weiterarbeiten. aber wie mache ich das mit einem Array von Dateien.

vielen dank

Soni

Link zu diesem Kommentar
Auf anderen Seiten teilen

aber wie mache ich das mit einem Array von Dateien.
Was soll denn ein "Array von Dateien" sein? Dateien sind logische Objekte in einem Dateisystem, die kannst du nicht in ein Array stecken.

Du kannst höchtens die Datennamen, Dateiinhalte oder Streamobjekte in Arrays ablegen.

Also was genau ist in dem Array drin, bzw. was genau soll rein?

Link zu diesem Kommentar
Auf anderen Seiten teilen

hi

also es sieht jetzt so aus. Ich lese eine Datei ein, mal egal woher. Diese Datei ist eine .min Datei und hat einen Header der in ASCI ist und einen data rumpf in hex. Ich hab jetzt versucht diese datei in einen String zu stecken da ich an eine ganz bestimmte stelle im Data Rumpf springen muss.

mein code sieht mal so aus.

ifstream file;

string fileName = "n38.min";

file.open(fileName.c_str(), ios::in);//| ios::binary); // oeffen im Binaer-Modus

if(file)

{

file.seekg(0, ios::end); // zum Ende Datei springen

long fileSize = file.tellg(); // Dateigroesse auslesen

file.seekg(0); // Zurueck zum Anfang springen

//int pos = file.tellg();

char *text = new char[fileSize]; // Speicher fuer Text anlegen

file.read(text, fileSize); // Text in 1 Rutsch auslesen

file.close();

cout << text;

delete text; // Speicher aufraeumen

}

else

{

cout << "Fehler!";

}

cin.get();

return 0;

jetzt zeigt es mit in der console nur den header an. wenn ich einen bestimmten bereich wähle zeigt er nur streifen. was kann ich machen um hier ein bestimmtes Byte auszulesen.

hilfe!!!

Link zu diesem Kommentar
Auf anderen Seiten teilen

jetzt zeigt es mit in der console nur den header an. wenn ich einen bestimmten bereich wähle zeigt er nur streifen.
Beides liegt daran, dass du versuchst, Binärdaten als Text auszugeben. Da darfst du dich nicht wundern, wenn die Ausgabe seltsam aussieht.

was kann ich machen um hier ein bestimmtes Byte auszulesen.
Ausgelesen hast du doch schon. Du musst nur die gelesenen Daten richtig interpretieren.
Link zu diesem Kommentar
Auf anderen Seiten teilen

Hi

also ich hab es jetzt soweit, das ich an einer bestimmten Stelle ein Byte als Dezimalzahl auslesen kann. Mein Problem ist jetzt noch, dass ich 2 Byte brauche. Diese 2 Byte geben eine Höhe über grund an. Ich brauche also 2 aufeinander folgende Byte als Dezimalzahl ausgegeben. Jemand ein Idee.

so sieht es bisher mit einem Byte auslesen aus.

char hex = '0'

ifstream myfile ("n26.min");

myfile.seekg(3500);

if(myfile)

myfile.get(hex);

printf("%d", hex);

cout << " "<< endl;

myfile.close();

Gruß

Sonja

Link zu diesem Kommentar
Auf anderen Seiten teilen

Mach doch einfach das, was ich dir schon hier schon mehrfach geraten habe. Wenn du das nicht verstehst, dann frag doch nach.

Angenommen, du brauchst einen vorzeichenlosen 16-Bit-Wert, und auf deinem System ist ein short 2 Byte groß:

unsigned short value = 0;

ifstream myfile ("n26.min");

myfile.seekg(3500);

myfile.read( reinterpret_cast<char*>( &value ), sizeof( unsigned short ) );
cout << value;
[/code] Jetzt kann es noch sein, dass du das auf einem Rechner mit Little-Endian-Architektur machst. Dann musst du noch die Bytereihenfolge vertauschen, weil der Wert laut Spezifikation Big-Endian ist:
[code]value = ((value & 0xff) << 8) | ((value & 0xff00) >> 8);

P.S.: cout und printf solltest du nicht mischen.

P.P.S: Du solltest die Datei mit dem binary-Flag öffnen, sonst kann es zu merkwürdigen Effekten kommen, wenn Bytes mit dem Wert eines Zeilenumbruchs in den Daten auftauchen.

Link zu diesem Kommentar
Auf anderen Seiten teilen

Danke

es funktioniert so. Da wär ich aber im Leben nicht drauf gekommen und komplett verstehen tu ich´s au net.

Wegen umdrehen war ich mir au erst sicher das ich das machen muss, aber da kommen keinen realen Werte raus deswegen fällt das umdrehen wohl doch weg.

Gruß

und danke nochmal

Sonja

Link zu diesem Kommentar
Auf anderen Seiten teilen

Was hast du denn für ein System auf dem du arbeitest?

Wenns ein normaler Intel PC ist dann solltest du auch Little Endian haben

Byte-Reihenfolge - Wikipedia

Wenn die Daten in der Datei jetzt wie Klotzkopp sagt Big Endian sind dann musst du die umdrehen. Sollte da dann nichts "vernünftiges" rauskommen hat das einen anderen Grund.

Link zu diesem Kommentar
Auf anderen Seiten teilen

hi

da ich wirklich keine kenntnisse in C++ habe tue ich mir momentan wahnsinnig schwer. Ich habe eine Methode die mir die benötigte Größe für ein Array berechnet. Jetzt möchte ich dieses Array so anlegen,dass ich es später mit bestimmten werten füllen kann. Hatte zuerst die größe als übergabe wert im constructor und hab dann dorkt im Konstruktor das array angelegt und erstmal mit aufeinanderfolgenden zahlen gefüllt. Da ich die Größe aber jetzt erst berechnen muss kann ich sie ja im constructor nicht mehr übergeben. Ich komm hier nicht klar da ich ein array ja nicht als rückgabewert bestimmen kann. Wie löse ich das am besten.

wollte in der Klasse ein short testarray[] anlegen aber da will er immer eine größe haben und die kenn ich ja noch nicht.

danke

Sonja

Link zu diesem Kommentar
Auf anderen Seiten teilen

Hallo

so weit so gut. Ich hab jetzt also mein Array und einen Ordner der alle Dateien enthält aus denen ich Daten auslesen muss. Wie kann ich ein Variable in meine Pfadangabe einfügen, so das ich immer den passenden Eintrag an die richtige Stelle im Array schreibe.

so sieht es jetzt aus.

ifstream myfile ("C:\\Dokumente und Einstellungen\\hagedornSo\\Eigene Dateien\\OPES15\\Hhendaten\\e85n26.min");

für e85 und n26 veränderbare Werte eingesetzt werden können,

also brauche ich etwas in der art:

ifstream myfile ("C:\\Dokumente und Einstellungen\\hagedornSo\\Eigene Dateien\\OPES15\\Hhendaten\\"+ variable+""+Variable2+".min");

weißt jemand wie das in C++ geht.

Danke

Sonja

Link zu diesem Kommentar
Auf anderen Seiten teilen

hab´s probiert, er gibt mir aber nur eine null aus wenn ich versuche an eine bestimmte stelle in dem file zu springen. Das ist aber falsch also vermute ich mal es klappt leider nicht.

unsigned short value = 0;

	ostringstream ss;

	int val1 = 85;

	int val2 = 26;


	ss << "C:\\Dokumente und Einstellungen\\hagedornSo\\Eigene Dateien\\OPES15\\Hhendaten\\e" 

	 << val1

	 << "n26.min";

	ifstream myfile( ss.str().c_str() );


	//ifstream myfile ("C:\\Dokumente und Einstellungen\\hagedornSo\\Eigene Dateien\\OPES15\\Hhendaten\\e85n26.min");


	myfile.seekg(3437);


	myfile.read( reinterpret_cast<char*>( &value ), sizeof( unsigned short ) );


	myfile.close();


	yourArray[3] = value;


	cout << "test array " << yourArray[3] << endl;


	return yourArray;

Link zu diesem Kommentar
Auf anderen Seiten teilen

hey

jetzt hatte ich das teil gerade am laufen. Mit Ifstream und so fort, da kommt mein Prof. und meint erhält nix von diesen neumodischen Sachen soll es mit Strings machen.

Mein Problem hier ist. Im 1. Schleifendurchlauf füllt er brav meinen String sData und liest mir die richtigen Daten aus. Aber im 2. Durchlauf steht irgendwie nichts mehr meine Datei in sData. Vielleicht kann mir jemand helfen, der sich mit diesen String Dingern auskennt.

	int iCornerLat;

	int	iCornerLong;

	int iLat = 0;

	int iLong = 0;

	int iPos = 0;


	unsigned short value = 0;

	ostringstream ss;

	ifstream myfile("000.txt");

	FILE* fp = NULL;

	char* sData;

	sData = new char[50000];

	char* sSub;

	sSub = new char[10];

	short** iwert = new (short*);



	for(int c = 0; c < size; c++){		//Schleife durchluft Array

		for(int i = 0; i <= iLong; i++){		//Jedes 1x 1 Zelle der Gaming Area ablaufen, erst Breiten dann Lngengrade

			for(int j = 0; j <= iLat; j++){

			if(fp != NULL)

				fclose(fp);

			ss << "C:\\Dokumente und Einstellungen\\hagedornSo\\Eigene Dateien\\OPES15\\Hhendaten\\e" 

				 << iCornerLong

				 << "n"

				 << iCornerLat

				 <<".min";

			fp = fopen( ss.str().c_str(), "r" );		

			if(fp){

				for(int a = 0; a < iNumberRecord; a++){

					for(int b = 0; b < iNumberElevation; b++){	

						int iByte = iConstStartData;

						iPos = iByte + (b * 2) + (a * iConstByteData);		//Byteposition im File berechne

						fgets(sData, 40000, fp);

						*iwert = (short*)&sData[iPos];  //!!!!!!!hier steht wenn b = 1 nix mehr

						value = **iwert;

						value = ((value & 0xff) << 8) | ((value & 0xff00) >> 8);

						c = c++;

					}

				}	

			}

			else {

				for(c; c < iValue; c++)	{		//wenn File nicht vorhanden 0 schreiben

					yourArray[c] = 0;

				}

			}

			iCornerLat = iCornerLat + 1;		

		}

		iCornerLong = iCornerLong + 1;

		iCornerLat = iCornerLat - iLat;

	 }

	}

	if(myfile)

		myfile.close();

sorry, dass den ganzen code reinstell wusste aber net wie ich´s ohne erklären soll.

danke

Sonja

Link zu diesem Kommentar
Auf anderen Seiten teilen

Aber im 2. Durchlauf steht irgendwie nichts mehr meine Datei in sData. Vielleicht kann mir jemand helfen, der sich mit diesen String Dingern auskennt.
Ich glaube, das hat mit Strings überhaupt nichts zu tun. Das Problem ist wahrscheinlich, dass du bei jedem Schleifendurchlauf die nächsten 40.000 Bytes aus der Datei liest. Ich vermute, einmal reicht.
Link zu diesem Kommentar
Auf anderen Seiten teilen

Ja hab das Problem gelöst.

Das nächste ist das wenn er das 2. mal in die j Schleife geht, dass er kein fp einliest obwohl die Datei existiert. Könnte das an dem fclose() liegen oder an dem oStringStream. Die if abfrage mit fclose habe ich schon mal auskommentiert das brachte aber nicht nichts. Hab mit stringstreams vorher noch nix gemacht, weiß daher nicht ob ich die in jedem Schleifendurchlauf neu schreiben darf.

Gruß Sonja

Link zu diesem Kommentar
Auf anderen Seiten teilen

Du könntest den Stringstream mit ss.str(""); zurücksetzen. Einfacher ist es aber wohl, wenn du den Stringstream erst in der Schleife anlegst, da wo du ihn auch benutzt. Die Methdoe, alle Variablen am Anfang zu deklarieren, ist ein Relikt aus C, das man in C++ nicht mehr braucht, und das auch nicht sonderlich sinnvoll ist.

Link zu diesem Kommentar
Auf anderen Seiten teilen

	iCount = 1;

	int i = 0;


	yourArray = new unsigned short [size];


	unsigned short value = 0;

	ostringstream ss;

	ifstream myfile("000.txt");

	FILE* fp = NULL;

	char* sData;

	sData = new char[size];

	char* sSub;

	sSub = new char[10];

	//short** iwert = new (short*);

	short** iwert = new short*;



	for(long c = 0; c < size; c++)		

	{

	 for(int i = 0; i <= iLong; i++)	

	 {

		for(int j = 0; j <= iLat; j++)

		{

			if(fp != NULL)

			{

				fclose(fp);

			}


			ostringstream ss;

			ss << "C:\\Dokumente und Einstellungen\\hagedornSo\\Eigene Dateien\\OPES15\\Hhendaten\\e" 

				 << iCornerLong

				 << "n"

				 << iCornerLat

				 <<".min"

				 << ends;

			fp = fopen( ss.str().c_str(), "r" );



			if(fp != NULL)

			{

			fgets(sData, size, fp);

				for(int a = 0; a < iNumberRecord; a++)

				{

					for(int b = 0; b < iNumberElevation; b++)

					{	


						int iByte = iConstStartData;

						iPos = iByte + (b * 2) + (a * iConstByteData);	

						*iwert = (short*)&sData[iPos];

						value = **iwert;

						value = ((value & 0xff) << 8) | ((value & 0xff00) >> 8);

						yourArray[c] = value;			

						c = c++;

					}


				}

			}

			if(fp == NULL) 

			{

				for(c; c < iValue; c++)		

				{

					yourArray[c] = 0;

				}

			}


			iCornerLat = iCornerLat + 1;		

		}


		iCornerLong = iCornerLong + 1;

		iCornerLat = iCornerLat - iLat-1;

	 }

	}

so leider gibt es immer noch Probleme. Es läuft alles optimal bis a =10. iPos = 5956, das ist korrekt und iwert sollte auf den richitigen Wert aus sData zeigen. Aber Value = 52685 und das gilt auch für alle nachfolgenden Durchläufe. c = 1200 an dieser Stelle. Eine Position davor ist alles noch korrekt. Ich weiß nicht was dieses 52685 sein soll und wo das herkommt. Einzige Idee die ich hatte ist,das ich vielleicht irgendwo drüberlauf aber das find ich nicht. In der Datei die ich einlese ist alles in Ordnung. Kein unterschied zu dem Schleifendurchlauf davor. Hoffe jemand hat eine Idee.

Gruß

Sonja

Link zu diesem Kommentar
Auf anderen Seiten teilen

Ist das ein Kuddelmuddel. Ich würde das erst mal so weit wie möglich vereinfachen.

Wenn iByte sowieso immer nur iConstStartData ist, brauchst du die Variable nicht.

Die Zeile

iPos = iByte + (b * 2) + (a * iConstByteData);	
wird dann zu
iPos = iConstStartData + (b * 2) + (a * iConstByteData);
und das wiederum zu
iPos = (b * 2) + ( (a + 1) * iConstByteData);
iWert brauchst du auch nicht.
value = *( (short*)&sData[iPos] );
tut's auch. Und das hier
c = c++;
erzeugt undefiniertes Verhalten. Wenn du c einfach nur hochzählen willst, mach das so:
++c;

Welchen Wert hat eigentlich iConstStartData?

Link zu diesem Kommentar
Auf anderen Seiten teilen

Dein Kommentar

Du kannst jetzt schreiben und Dich später registrieren. Wenn Du ein Konto hast, melde Dich jetzt an, um unter Deinem Benutzernamen zu schreiben.

Gast
Auf dieses Thema antworten...

×   Du hast formatierten Text eingefügt.   Formatierung wiederherstellen

  Nur 75 Emojis sind erlaubt.

×   Dein Link wurde automatisch eingebettet.   Einbetten rückgängig machen und als Link darstellen

×   Dein vorheriger Inhalt wurde wiederhergestellt.   Editor leeren

×   Du kannst Bilder nicht direkt einfügen. Lade Bilder hoch oder lade sie von einer URL.

Fachinformatiker.de, 2024 by SE Internet Services

fidelogo_small.png

Schicke uns eine Nachricht!

Fachinformatiker.de ist die größte IT-Community
rund um Ausbildung, Job, Weiterbildung für IT-Fachkräfte.

Fachinformatiker.de App

Download on the App Store
Get it on Google Play

Kontakt

Hier werben?
Oder sende eine E-Mail an

Social media u. feeds

Jobboard für Fachinformatiker und IT-Fachkräfte

×
×
  • Neu erstellen...