Vorheriges Thema anzeigen :: Nächstes Thema anzeigen |
Autor |
Nachricht |
DirectXer Dark JLI'ler
Anmeldedatum: 05.02.2005 Beiträge: 1201 Wohnort: Köln Medaillen: Keine
|
Verfasst am: 02.08.2007, 21:50 Titel: |
|
|
David hat Folgendes geschrieben: | Wieso nich so?
CPP: | std::string str( laenge, 0 );
GetWindowText( hWnd, &str[ 0 ], laenge );
|
|
das geht? kewl das wusste ich auch nicht. Ich hab immer insert-iteratoren benutzt...
Gruß DXer |
|
Nach oben |
|
|
GreveN JLI Master
Alter: 38 Anmeldedatum: 08.01.2004 Beiträge: 901 Wohnort: Sachsen - Dresden Medaillen: Keine
|
Verfasst am: 02.08.2007, 22:01 Titel: |
|
|
DirectXer hat Folgendes geschrieben: | David hat Folgendes geschrieben: | Wieso nich so? :)
CPP: | std::string str( laenge, 0 );
GetWindowText( hWnd, &str[ 0 ], laenge );
|
|
das geht? kewl das wusste ich auch nicht. Ich hab immer insert-iteratoren benutzt...
Gruß DXer |
Dito, man lernt eben doch nie aus... ;) |
|
Nach oben |
|
|
RebornX JLI'ler
Anmeldedatum: 16.03.2007 Beiträge: 169
Medaillen: Keine
|
Verfasst am: 03.08.2007, 11:16 Titel: |
|
|
David hat Folgendes geschrieben: | Wieso nich so?
CPP: | std::string str( laenge, 0 );
GetWindowText( hWnd, &str[ 0 ], laenge );
|
|
Ehm das verstehe ich nicht...
Der String "str" ist jetzt eine Funktion und array zugleich ??
hama _________________ Besucht meine Seite:
www.cpparchiv.dl.am |
|
Nach oben |
|
|
David Super JLI'ler
Alter: 39 Anmeldedatum: 13.10.2005 Beiträge: 315
Medaillen: Keine
|
Verfasst am: 03.08.2007, 11:33 Titel: |
|
|
Ne, str ist nichts von beiden! |
|
Nach oben |
|
|
RebornX JLI'ler
Anmeldedatum: 16.03.2007 Beiträge: 169
Medaillen: Keine
|
Verfasst am: 03.08.2007, 11:39 Titel: |
|
|
hm?
Aber nach dem str sind doch runde klammern mit laenge und einer 0
und in der GetWindowText Funktion steht es als "&str[ 0 ]"
Also mit eckigen Klammern und der Position 0 ? _________________ Besucht meine Seite:
www.cpparchiv.dl.am |
|
Nach oben |
|
|
David Super JLI'ler
Alter: 39 Anmeldedatum: 13.10.2005 Beiträge: 315
Medaillen: Keine
|
Verfasst am: 03.08.2007, 11:51 Titel: |
|
|
Hier die Erklährung:
Folgende Zeile ruft einen überladenen Konstruktor von std::basic_string auf:
CPP: | std::string str( laenge, 0 );
|
Nämlich diesen Konstruktor:
CPP: | std::basic_string< CharT, Traits, Alloc, >::basic_string( size_type n, CharT c );
|
Der Konstruktor reserviert 'n' Byte für den String und kopiert in jedes Byte den Wert von c. Der String enthält also 'laenge' Bytes mit dem Wert '0'.
In der zweiten Zeile wird an die Funktion GetWindowText im 2. Parameter die Adresse des ersten Elements der Daten des Stringobjekts übergeben. Das funktioniert weil die Daten am Stück gespeichert werden (im Stringobjekt) und weil die Funktion operator[]( std::size_t ) auch Schreibzugriff erlaubt.
CPP: | GetWindowText( hWnd, &str[ 0 ], laenge );
|
|
|
Nach oben |
|
|
RebornX JLI'ler
Anmeldedatum: 16.03.2007 Beiträge: 169
Medaillen: Keine
|
Verfasst am: 03.08.2007, 12:54 Titel: |
|
|
Oh gott ich mache das mit array-Zeichenketten... _________________ Besucht meine Seite:
www.cpparchiv.dl.am |
|
Nach oben |
|
|
DirectXer Dark JLI'ler
Anmeldedatum: 05.02.2005 Beiträge: 1201 Wohnort: Köln Medaillen: Keine
|
Verfasst am: 03.08.2007, 13:12 Titel: |
|
|
RebornX hat Folgendes geschrieben: | Oh gott ich mache das mit array-Zeichenketten... |
nein!, das ist definitiv die falsche Richtung Ich erklär das nochmal etwas vereinfacht:
Ein Vorteil von strings (so nenne ich jetz mal die nicht-cstrings) ist, dass man die Größe nicht vorher festlegen muss. Bei C-Strings musst du das in eckigen Klammern z.B. für das Array machen. Kennst du dich ein bisschen mit OOP (also Klassen und so, Konstruktor/Destruktor...) aus? Da kann man ja für jede Klasse mehrere Konstruktoren definieren. Die sehen z.B. so aus CPP: | class Foo
{
public:
// Standard Konstruktor, wird in den meisten trivialen fällen bei Erstellung
// des Objetks aufgerufen
Foo();
// Konstruktor mit zwe Argumenten (Konstruktoren sind nur Funktionen
// ohne expliziten Rückgabewert, die man genauso gut mit Argumenten
// aufrufen kann wie normale Funktionen)
Foo( float argument1, int argument2 );
}; |
Diese kannst du dann so aufrufen: CPP: |
// dieses Objekt ruft standardmäßig Foo::Foo(), also den standard-Konstruktor auf
Foo obj1;
// dieses Objekt soll beim erstellen explizit den 2. Konstruktor aufrufen,
// deshalb werden die nötigen Argumente übergeben
Foo obj2( einFloat, einInt ); |
Genauso ist das bei strings, nur das die nicht 2 sondern 14 ( )versch. Konstruktoren haben. So kann man z.B. folgendes machen: CPP: | std::string str( "dies ist ein string" );
// ist äquivalent (nicht 100% gleich, aber mit dem gleichen Effekt nur langsamer) zu:
std::string str = "dies ist ein string"; | Ein weiterer Konstruktor ist der, den david oben benutzt hat; diesem übergibt man 2 Argumente: nämlich die gewünschte Länge an zu reservierendem Speicher und ein Wert mit dem alle Zeichen des Strings gefüllt werden sollen, also hier 0 für das Terminierungszeichen. Man kann also Folgendes vergleichen: CPP: | std::string str( 50, 0 );
// in C ungf:
char str[50];
memset( str, 0, sizeof(str) ); | Dabei bist du bei strings aber nicht an diese Länge gebunden: Wird der string größer als 50 Zeichen, wird automatisch neuer Speicher reserviert.
Das &str[ 0 ] in davids Beispiel heißt (wie er schon gesagt hat): gebe die Addresse des ersten Elements im String (also ein char*-Pointer) zurück. An diese Position schreibt die WinAPI-Funktion nun den Text. Damit nach dieser Addresse auch noch genügend Platz dafür vorreserviert ist, benutzt du eben den Konstruktor (50, 0).
Übr: Bei normalen Arrays ist die Schreibweise CPP: | int array1[ 20 ];
funktion( array1 ); | gleich zu dieser Schreibweise CPP: | funktion( &array1[0] ) | Nur bei strings musst du eben die 2. nehmen, da ein string nunmal nicht von natur aus ein char*-Pointer ist wie ein C-String, sondern du damit erst an diesen Pointer kommen musst.
Gruß DXer |
|
Nach oben |
|
|
RebornX JLI'ler
Anmeldedatum: 16.03.2007 Beiträge: 169
Medaillen: Keine
|
Verfasst am: 03.08.2007, 13:34 Titel: |
|
|
OK jetzt habe ich wieder was dazu gelernt.
Ich wusste vorher gar nicht das std::string eine eigene Klasse ist
und das ich bei jedem definieren eines strings eine ganze Klasse ( ) erstelle.
Ich dachte immer das der Compiler die std::strings durch irgendeinen Trick so "mächtig" macht.
(lol ich sage aber selber auch immer "ich muss noch die String Klasse includieren" und habe es nichtmal gemerkt XD)
Naja aber eins verstehe ich nicht, bzw kannte ich vorher noch nicht:
Unzwar das man auch eckige Klammern bei Klassen einsetzten kann?
Wie funktioniert den sowas?
Funktioniert das genau so wie bei Structuren? _________________ Besucht meine Seite:
www.cpparchiv.dl.am
Zuletzt bearbeitet von RebornX am 03.08.2007, 14:28, insgesamt einmal bearbeitet |
|
Nach oben |
|
|
Jonathan_Klein Living Legend
Alter: 37 Anmeldedatum: 17.02.2003 Beiträge: 3433 Wohnort: Siegerland Medaillen: Keine
|
Verfasst am: 03.08.2007, 14:23 Titel: |
|
|
Du erstellst keine Klasse, du erstellst Objekte von Klassen. Das ist ein kleiner unterschied.
<< benutzt du, indme du Operatoren überlädst. Man kann dem COmpiler sagen, was passierne soll, wenn man Objekt1+Objekte2 schreibt. Zum Beispiel für eine Bruchklasse, wo man beim adieren auch immer noch auf die Nenner achten muss. Einfach mal danach googeln, mit der Technik kann amn sehr coole Sachen machen. Ein Beispiel:
http://www.minet.uni-jena.de/~msk/cpp/node19.html _________________ https://jonathank.de/games/ |
|
Nach oben |
|
|
RebornX JLI'ler
Anmeldedatum: 16.03.2007 Beiträge: 169
Medaillen: Keine
|
Verfasst am: 03.08.2007, 14:30 Titel: |
|
|
Ehm diese zwei << war ein Tippfehler^^
Ich habe eigentlich diese eckigen klammern gemeint []
Aba das es bei Klassen auch noch diese << gibt wusst ich auch nicht _________________ Besucht meine Seite:
www.cpparchiv.dl.am |
|
Nach oben |
|
|
Jonathan_Klein Living Legend
Alter: 37 Anmeldedatum: 17.02.2003 Beiträge: 3433 Wohnort: Siegerland Medaillen: Keine
|
|
Nach oben |
|
|
RebornX JLI'ler
Anmeldedatum: 16.03.2007 Beiträge: 169
Medaillen: Keine
|
Verfasst am: 03.08.2007, 14:49 Titel: |
|
|
Also das gleiche ? hama
Nagut ich habe nochmal ne kurze Frage:
Unzwar wie hieß nochmal diese Funktion zum erstellen eines WORD (mit LOWORD und HIWORD) ?? _________________ Besucht meine Seite:
www.cpparchiv.dl.am |
|
Nach oben |
|
|
David Super JLI'ler
Alter: 39 Anmeldedatum: 13.10.2005 Beiträge: 315
Medaillen: Keine
|
Verfasst am: 03.08.2007, 15:15 Titel: |
|
|
RebornX hat Folgendes geschrieben: |
Oh gott ich mache das mit array-Zeichenketten...
|
Wieso? Ist doch viel einfacher so?
DirectXer hat Folgendes geschrieben: |
CPP: | std::string str( "dies ist ein string" );
// ist äquivalent (nicht 100% gleich, aber mit dem gleichen Effekt nur langsamer) zu:
std::string str = "dies ist ein string"; |
|
Ist sogar exakt das Selbe!
RebornX hat Folgendes geschrieben: |
OK jetzt habe ich wieder was dazu gelernt.
Ich wusste vorher gar nicht das std::string eine eigene Klasse ist
und das ich bei jedem definieren eines strings eine ganze Klasse ( Exclamation ) erstelle. |
std::string ist auch garkeine Klasse sondern eine Typendefinition. Die schaut so aus:
CPP: | typedef basic_string< char > string;
|
Was da verwendet wird ist auch keine Klasse sondern ein Klassentemplate, nämlich std::basic_string.
Und was ist das Problem für jeden String ein Objekt zu erstellen?
RebornX hat Folgendes geschrieben: |
Ehm diese zwei << war ein Tippfehler^^ Laughing
Ich habe eigentlich diese eckigen klammern gemeint []
Aba das es bei Klassen auch noch diese << gibt wusst ich auch nicht
|
Simples Beispiel:
CPP: | struct foo
{
typedef unsigned char type;
typedef type* ptr_type;
typedef type& ref_type;
foo( const char* text )
: data( 0 )
{
len = strlen( text );
data = new type[ len+1 ];
memset( data, 0, len+1 );
memcpy( data, text, len );
}
~foo()
{
delete [] data;
}
// Schreibzugriff
ref_type operator[]( std::size_t idx ) const
{
return data[ idx ];
}
// Lesezugriff
ref_type operator[]( std::size_t idx )
{
return data[ idx ];
}
const ptr_type c_str() const
{
return data;
}
private:
std::size_t len;
ptr_type data;
};
int main()
{
foo x( "Hallo Welt" );
std::cout << x.c_str() << std::endl; // "Hallo Welt"
std::cout << x[ 0 ] << x[ 1 ] << x[ 2 ] << x[ 3 ] << x[ 4 ] << std::endl; // "Hallo"
x[ 1 ] = 'A';
std::cout << x.c_str() << std::endl; // "HAllo Welt"
std::cin.get();
}
|
RebornX hat Folgendes geschrieben: |
Also das gleiche ? hama Shocked
Nagut ich habe nochmal ne kurze Frage:
Unzwar wie hieß nochmal diese Funktion zum erstellen eines WORD (mit LOWORD und HIWORD) ??
|
Nein, ist nicht das Gleiche! Und die Funktionen die du meinst sind Makros und heißen: HIWORD und LOWORD. |
|
Nach oben |
|
|
RebornX JLI'ler
Anmeldedatum: 16.03.2007 Beiträge: 169
Medaillen: Keine
|
Verfasst am: 03.08.2007, 16:22 Titel: |
|
|
David hat Folgendes geschrieben: |
RebornX hat Folgendes geschrieben: |
Also das gleiche ? hama Shocked
Nagut ich habe nochmal ne kurze Frage:
Unzwar wie hieß nochmal diese Funktion zum erstellen eines WORD (mit LOWORD und HIWORD) ??
|
Nein, ist nicht das Gleiche! Und die Funktionen die du meinst sind Makros und heißen: HIWORD und LOWORD. |
Nee da gab es doch so eine Funktion die so ein WORD erstellt.
Die hieß irgendwie CreateWord(LOWORD, HIWORD) oder DWORD(LOWORD, HIWORD) oder so.
In irgendeinem Buch oder auf irgend einer Seite habe ich das gelesen doch ich weiß nicht mehr auf welcher Seite bzw in welchem Buch.
Auf jeden Fall habe ich das Problem bei SendMessage das ich WPARAM ein HIWORD und ein LOWORD zuweisen muss. _________________ Besucht meine Seite:
www.cpparchiv.dl.am |
|
Nach oben |
|
|
|