Herzlich Willkommen, lieber Gast!
  Sie befinden sich hier:

  Forum » C / C++ (ANSI-Standard) » Zur Laufzeit Variablengröße bestimmen, wie?

Forum | Hilfe | Team | Links | Impressum | > Suche < | Mitglieder | Registrieren | Einloggen
  Quicklinks: MSDN-Online || STL || clib Reference Grundlagen || Literatur || E-Books || Zubehör || > F.A.Q. < || Downloads   

Autor Thread - Seiten: > 1 <
000
03.01.2004, 20:40 Uhr
(un)wissender
Niveauwart



C++:
template<typename string_type>        
int TCPSocket::writeString( const string_type &stringToWrite )
{        
    unsigned int nLetters = 0;
    for(typename string_type::iterator i = stringToWrite.begin();        
         i != stringToWrite.end();
         ++i, ++nLetters)
    {      
        if(write(&*i, sizeof(*i)) == SOCKET_ERROR)
            encodeWinsockErrorAndThrowException();        
    }
    
    return nLetters;
}



So, das ist der code.
Ich muss wissen, wie groß in Bytes der Inhalt des jeweiligen Iterators ist, ich habe hier mit sizeof gemacht, aber das geht, glaube ich, nur zu Compilezeit, oder?
Wenn es auch dynamisch geht, dann hat sich meine Frage erledigt.
Hintergrund ist der, das z.B. UTF-8 Letter nicht immer die gleiche Größe haben, darum kann die Größe der einzelnen Letter im String variiieren.
Kann man eigenlich dieses &*i cooler schreiben?
(Ich möcht den Pointer, den der Iterator kapselt, haben.)

Die Signatur von write() ist:

C++:
int TCPSocket::write( const void *pData,
                      unsigned int nBytes,
                      unsigned int flags = 0 )


--
Wer früher stirbt ist länger tot.

Dieser Post wurde am 03.01.2004 um 21:07 Uhr von (un)wissender editiert.
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
001
03.01.2004, 20:48 Uhr
(un)wissender
Niveauwart


Ach ja, noch eine Frage:
Gibt es einen generellen Weg (ASCII, UTF-8, etc.), festzustellen, ob ein Zeichen ein Linebreak ist?

Funktioniert sowas immer?

C++:
verschiedenKodierteTypen meinChar;
if(meinChar == '\n')
//tuwas...


--
Wer früher stirbt ist länger tot.

Dieser Post wurde am 03.01.2004 um 20:49 Uhr von (un)wissender editiert.
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
002
04.01.2004, 02:02 Uhr
0xdeadbeef
Gott
(Operator)


Naja, der Inhalt des Iterators ist wohl eine Klasse, die einen Pointer auf einen dynamisch alloziierten Speicherbereich enthalten soll. Das bedeutet, dass du mit &*i bestenfalls auf die Speicheradresse der entsprechenden Klasse, nicht auf den eigentlichen String kommst, und damit wird der ganze Quatsch hinfällig. Was du willst, ist ein Pointer auf ein Byte-Array, dass du in den Socket schreiben kannst. Eine sinnvolle Idee bei sowas wäre, sich an die Konvention der STL zu halten (zumal du die meiste Zeit wohl eh std::strings ausgeben willst) und zwei Methoden string_type::c_str() und string::type_size() zur Verfügung stellst, die die entsprechende Info ausgeben und dann

C++:
write(i->c_str(), i->size())


benutzt.
--
Einfachheit ist Voraussetzung für Zuverlässigkeit.
-- Edsger Wybe Dijkstra
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
003
04.01.2004, 08:28 Uhr
(un)wissender
Niveauwart


Nein, mit *& bekomme ich genau das was ich will, nämlich den Pointer der vom Iterator gekapselt wird. Durch * bekomme ich das Objekt und durch & bekomme ich die Adresse.
Dein Bsp. kann so nicht funktionieren, weil i ein Iterator ist, der auf ein char zeigt (bei std::string), versuch mal für ein char* -> seize() aufzurufen...
Wenn du meinst das ich das mit Strings machen soll, dann geht das vermutlich auch nicht, weil ich glaube (ich weiß es nicht!), das UTF-8 Strings unterschiedlich große Lettern haben (nicht wie std:string, alle 1 Byte), da kommt nicht size() vermutlich nicht nicht an die korrekte Bytezahl, sonder nur an die Anzahl der Buchstaben.
--
Wer früher stirbt ist länger tot.
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
004
04.01.2004, 14:06 Uhr
Guybrush Threepwood
Gefürchteter Pirat
(Operator)


Unter Windows gibt es die Funktion _msize(), ist aber kein standart. Vielleicht hilft`s dir ja trotzdem weiter.


Zitat:
_msize
Returns the size of a memory block allocated in the heap.

size_t _msize( void *memblock );

 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
005
04.01.2004, 16:09 Uhr
0xdeadbeef
Gott
(Operator)


Wenn du nen char* benutzt, kommst du vom Standard her nicht an die Länge ran. Außerdem macht es wenig Sinn, ne Template-Funktion zu schreiben, wenn es dir nur um einen Datentyp geht. Ansonsten kannst du ja für char* noch spezialisieren.

Der STL-Weg an dieser Stelle wäre wohl, durch zwei Iteratoren den Bereich anzugeben, der ins Socket geschrieben werden soll. Also:

C++:
template <typename iter_type> int TCPSocket::writeString(iter_type start, iter_type end)
{        
    unsigned int nLetters;
    for(iter_type i = start; i != end; ++i)
    {      
        if(write(*i, sizeof(*i)) == SOCKET_ERROR)
            encodeWinsockErrorAndThrowException();        
    }
    
    return nLetters;
}


Richtig sinnvoll wäre es aber, erstmal ostream auf Socket zu implementieren; der Inhaltstyp des Iterators weiß dann selbst, wie er sich in den Stream schreiben will.
--
Einfachheit ist Voraussetzung für Zuverlässigkeit.
-- Edsger Wybe Dijkstra
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
006
04.01.2004, 17:08 Uhr
(un)wissender
Niveauwart


Tja, das ist das Problem.
Ich kenne ja den Datentyp nicht zwangsläufig(darum bringt mir auch stream nichts), noch weiß ich, ob ein Letter auf dem Heap ist.
Stellt euch vor, das ganze soll für wxString, std::string, std::wstring, glib::ustring... funktionieren.
Nun das ganze scheint nicht trivial zu sein, werde mit die UTF-8 Kodierung mal ansehen, nur die macht ja eigentlich Probleme. Alle anderen mit bekannten Stringtypen haben immer gleich große char_typen.
--
Wer früher stirbt ist länger tot.
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
007
04.01.2004, 17:26 Uhr
(un)wissender
Niveauwart


Ha, UTF-8 verbietet weitere nullen, um den String darzustellen.
Ich kann also c_str() mit strlen() nehmen, toll.
--
Wer früher stirbt ist länger tot.
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
008
04.01.2004, 17:34 Uhr
0xdeadbeef
Gott
(Operator)


Gerade deswegen macht doch ein ostream Sinn. Die ganzen Standardtypen bringen doch schon einen operator<< für ostreams mit, und für eigene Typen ist es ziemlich sinnvoll, diesen Operator zu definieren. Was das mit den Nullen angeht - std::string kann auch Null-Zeichen im String verwalten. strlen funktioniert da nicht mehr.
--
Einfachheit ist Voraussetzung für Zuverlässigkeit.
-- Edsger Wybe Dijkstra

Dieser Post wurde am 04.01.2004 um 17:35 Uhr von 0xdeadbeef editiert.
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
Seiten: > 1 <     [ C / C++ (ANSI-Standard) ]  


ThWBoard 2.73 FloSoft-Edition
© by Paul Baecher & Felix Gonschorek (www.thwboard.de)

Anpassungen des Forums
© by Flo-Soft (www.flo-soft.de)

Sie sind Besucher: