Seek unter CLR

Olaf Lehmann

Mitglied
Hallo,

hab bisher Windows Programme mit MFC geschrieben, mit der ExpressEdtion 2008 geht das nun nicht mehr.
Die Umstellung ist echt hart!

Momentanes Problem. Ich muss aus einer Datei Daten auslesen und zwiaschendurch immer überspringen.
Mit MFC gabs den Seek befehl:
Code:
Datei.Seek(4,CFile::current);]
z.B.
Mit CLR dachte ich wenn ich schreibe:
Code:
Datei->
wird mir automatisch Seek angeboten, aber denkste. Im Kontextmenu finde ich Peek, und Read, usw., aber kein Seek.

Dummerweise komme ich mit der Hilfe überhaupt nicht klar. Wenn ich zum Beispiel über Index gehe, finde ich nur Informationen über die Visual Dateien. Unter Suchen System::IO einzugeben, hat mich auch nicht weitergebracht; Google ebenfalls nicht, wohl weil der Befehl anders heisst.
Wo kann ich den bloß über System::IO nachlesen. Mein Buch geht an der Stelle auch nicht in die Tiefe.

Echt anstrengend. Ich verstehe das nicht. Bisher hieß der Befehl immer Seek. Auch bei Konsolen unter iostream und in Basic?

MfG Olaf
 
Der neue Code? Ist noch ganz kurz. Ein Teil, der im Button1 steckt geht so:
Code:
String ^sPfad="C:\\Sierra\\gpl\\replay\\361rplyA.rpy";
this->label1->Text=sPfad;
			
StreamReader ^Datei = gcnew StreamReader(sPfad);

Datei->
//Datei.seekg(0,ios_base::end);  //reale Dateigröße ermitteln
//int Lange = Datei.tellg();     //und Lange zuweisen
Datei->Close();
Alles andre was noch in dem Button steckt ist Versuchsblödsinn und würde nur verwirren...
Wenn ich jetzt hinter - ein > setze klappt ein PopuP Menu auf, indem ich Seek vergeblich suche.
Die beiden auskommentierten Zeilen sind alter CFile (Windows ohne CLR) Code.

MfG Olaf

P.S.: Der alte Code ist fast unendlich lang: Was immer wieder vorkommt sind so ähnliche Befehle:
Code:
 Datei.Read((char *) &Wert,4);
Datei.Seek(4,CFile::current);   //zum erster Trainingsrundenanzahlanzeige rücken
In der Regel werden also Integer Werte eingelesen und dann wird zum nächsten interessanten Wert gesprungen. Die Datein werden nicht von mir selber gemacht, sondern sind replaydateien eines Rernnspiels, deshalb muss viel übersprungen werden.
 
Zuletzt bearbeitet:
Die StreamReader-Klasse bietet einen Member BaseStream, welcher wiederum den zu Grunde liegenden Stream repräsentiert, welcher wiederum die folgende Eigenschaft binhält: Position
C++:
Datei->BaseStream->Position += 4;
 
Bist du dir eigentlich sicher, welche Sprache du verwenden willst?
Hier im Forum fällt mir immer wieder auf, das Leute nicht wissen, in welcher Sprache sie eigentlich programmieren.

Vorher hast du MFC verwendet-das ist C++.
Den Code, den du jetzt da hast, ist C++CLI; das hat "C++" zwar im Namen, basiert aber auf dem .NET-Framework, wie zB C#
 
Danke Cromon,

ja, Position ist gut. Unter BaseStream hatte ich nicht geguckt.

Aber es gibt sofort das nächste Problem.
Erstmal ein Stück Code:
Code:
int Wert; 
String ^sStrecke;
array <unsigned char> ^Buffer=gcnew array <unsigned char>(200);
#define ORPL 1280332367    //Einsprungwert ORPL
#define BTPL 1280332866	
String ^sPfad="C:\\Sierra\\gpl\\replay\\361rplyA.rpy";
this->label1->Text=sPfad;
				 //char Pfadname[80]="";

StreamReader ^Datei = gcnew StreamReader(sPfad);

Datei->BaseStream->Position=128;
sStrecke=Datei->ReadLine();
this->label1->Text=sStrecke;

Datei->BaseStream->Position=128;
//Datei->BaseStream->Read(Buffer,0,6);
//this->label1->Text=Buffer->ToString();
In diesem Falle muss/soll eine Zeichenkette (kein Integer) ausgelesen werden. Das klappt auch soweit (wenn die letzten beiden Zeilen auskommentiert sind) perfekt.
Das Problem ist aber, dass die Datei so aufgebaut aufgebaut ist, dass es zu ReadLine() nicht passt. Wenn ich ReadLine() verwende, wird bis zum nächsten Nullterminierungszeichen ausgelesen. Nun ist aber der String unterschiedlich lang. In der Datei sind 6Byte reserviert, wenn der String nur 4 Zeichen lang ist, kommen ma Ende 2 NULLTerminierungszeichen, falls er 5Zeichen lang ist 1 * NULL, usw. Ich muss also in jedem Falle 6 Byte auslesen, dass ich danach an der richtigen Stelle bin, weil ich sonst in der Datei "verrutsche". Ich muss dann mit Position += arbeiten und kann nicht Position = verwenden, dass heisst ich muss vom "Internen Dateizeiger" weiterrechnen.

Wenn ich nun die untere Methode die letzten beiden Zeilen verwende (auskommentiere) wird plötzlich in Label1 was ganz verrücktes angezeigt, nämlich:
Code:
System.Byte[]
?

Gruß Olaf

@sheel: hab jetzt erst Deinen Eintrag gesehen. Bis vor einem Monat war mir in der Tat der Unterschied zwischen C++ und .NET und C# völlig unklar. Von CLR hatte ich noch nie was gehört. Mittlerweile wird mir immer klarer wie groß der Unterschied zwischen C++ und .Net ist, obwohl ich immer wieder lese, dass es fast das gleiche wäre.:confused:
Mir scheint, ich bin hier eigentlich auch im falschen Forum.

Ich bin mehr oder minder gezwungen Windows Forms / CLR (also praktisch .NET) zu verwenden, weil unter Vista VisualC++6.0 MFC nicht mehr unterstützt wird, jedenfalls in der Express Version nicht.
 
Zuletzt bearbeitet:
Ja, gehört eigentlich in den .NET-Bereich
C++CLI ist ja quasi C++ mit den .NET-Klassen, die es auch in C# und allen anderen .NET-Sprachen gibt. Der StreamReader gehört auch dazu.

Die Syntax etc ist leider auch nicht ganz gleich,
zB "Klassexyz ^meineklasse=gcnew..."

MFC gibts soweit ich weiss leider wirklich nur noch in den kostenpflichtigen Ausgaben...aber:
warum zwingt dich das, auf .NET umzusteigen?

MFC ist nicht das einzige GUI-Framework. Weitere Beispiele wären Qt, wxWidgets...

Deswegen muss man doch nicht die ganze Sprache wechseln
Die von der Gui unabhängigen Teile kannst du so wenigstens behalten/weiterverwenden.
 
Dass du System.Byte[] angezeigt bekommst ist ganz normal. Hat ein gewisser Typ ToString nicht überschrieben (wie zum Beispiel System.Int32), so wird einfach der Name des Typs ausgegeben. Wenn du die ausgelesenen 6 Bytes zu einem String konvertieren willst musst du eine Encoding-Klasse verwenden:
C++:
cli::array<unsigned char>^ buffer = gcnew cli::array<unsigned char>(6);
//read 6 bytes
System::String^ text = System::Text::Encoding::ASCII->GetString(buffer);
label1->Text = text;
 
Danke GST,

nun klappt das Einlesen auch von Zeichenketten.:)
Das Einlesen musste ich nochmal ändern in:
Code:
Buffer=Datei->ReadBytes(6);
ReadChars scheint w_chars zu erwarten.

MfG Olaf

Jetzt müsste ich eigentlich erstmal alleine weiterkommen.
 
Jap, da .NET immer Unicode für Texte verwendet ist der Basistyp char auch wchar_t und nicht das was man sich vielleicht gewohnt ist.
 
Zurück