Newsgroup: it.comp.lang.c++
Titolo: Tipi di dato string

Salve
Esiste un tipo di dato string?
Se esiste cosa devo includere per poterlo usare?
E' simile ad un puntatore a carattere?
Quali sono le differenze?
Ciao e Grazie.
Giacomo

 E' simile ad un puntatore a carattere?
Direi di no. 
std::string è una classe con una sua interfaccia, documentata in qualsiasi
manuale o tutorial decente del C++. E' il modo standard in cui si
dovrebbero trattare le stringhe in C++. Chiedersi se ci siano o meno
somiglianze con le cosiddette null-terminated string del C mi sembra
fuorviante. Ma se proprio vogliamo dire qualcosa, potremmo accennare al
fatto che le std::string possono contenere dei null, mentre le "stringhe"
del C no.
 
Max


 Quali sono le differenze?
Rispetto ad un puntatore a carattere moltissime. Ad esempio gestisce
l'allocazione di memoria in maniera dinamica, ottimizzata e trasparente.
Offre una ricca dotazione di metodi per il trattamento del testo.
Fornisce dei comodi operatori come quello di concatenazione (+).
EMG

 Quali sono le differenze?
L'uno e` una stringa, l'altro un puntatore a carattere.
Alex

Ho provato a fare una cosa del genere:
#include <string>
e:
string  stringa;
Ma mi da il seguente errore:
error C2146: syntax error : missing ';' before identifier 'stringa'
Come mai?
Ciao
Giacomo

 wrote in message
38e75564...@news.tiscalinet.it...

Perche` non ha detto
std::string stringa;
oppure
using std::string;
string stringa;
ecc.
La #include <string> definisce il nome del tipo std::string, cioe`
nel namespace std; se non vuoi usare l'esplicito std:: per dire
di che namespace stai parlando, devi dunque importare questo
identificatore nel tuo scope con la using.
Alex

Alex
Giacomo

 Posso usare una variabile string nell'API GetWindowText?
E` una questione specifica di una piattaforma, comunque la
risposta e` no; consiglio it.comp.programmare.win32 per
altre questioni specificamente relative alle API di Windows.
Se hai una funzione di una qualsiasi libreria (anche le API di
Windows!-) che vuole come argomenti l'indirizzo di un array
di caratteri, e la sua lunghezza, al fine di riempire l'array
stesso (e magari torna la lunghezza con cui lo ha riempito),
ad esempio:
    int dammideicaratteri(char* buffer, int maxlength);
puoi comunque usare std::string, ma devi decidere in ogni
caso la "maxlength":
    inline std::string ricoprimento(int maxlength)
    {
        std::string s(maxlength,0);
        int reslen =
            dammideicaratteri(const_cast<char*>(s.data),
                maxlength);
        s.resize(reslen);
        return s;
    }
questo approccio non e` garantito al 100%, perche` non
e` detto che il const_cast<> funzioni su tutti i futuri
compilatori, ma almeno funziona su quelli esistenti (e
in futuro si puo` sperare di avere messo in pensione le
vecchie librerie orientate al solo C...:-).
Un approccio "sicuro al 100%" e` quello di usare uno
std::vector<char> (il _suo_ begin() deve tornare
un char* usabile ai tuoi fini...), ma per trasformarlo
in std::string al momento del return occorre che il
tuo compilatore (e la sua libreria standard) supportino
correttamente i costruttori-template...:
    inline std::string ricoprimento(int maxlength)
    {
        std::vector<char> s(maxlength);
        int reslen =
            dammideicaratteri(s.begin(),maxlength);
        return std::string(s.begin(),s.begin()+reslen);
    }
Ti conviene comunque studiare questo tipo di soluzioni
piuttosto che non impelagarti con costrutti di basso
livello come array e puntatori, visto che puoi evitarlo.
Alex

 vecchie librerie orientate al solo C...:-).
Però se veramente le API dei vari sistemi operativi cominceranno ad
utilizzare i tipi della libreria standard del C++ temo diventerà ancora
più difficile di quanto lo sia ora adattare altri linguaggi alla
programmazione sotto tali ambienti, o sbaglio?
EMG

 wrote in message
news:38E84CC3...@flashnet.it...

Penso di si`.  E` piu` probabile d'altra parte che i "tipi"
usati lo siano in termini di standard di componentizzazione
(probabilmente COM, forse Corba), language-independent
per definizione.
Alex

Alex
Giacomo

 e mi dice:
Se usi caratt.begin(), anzichè caratt.begin, avrai senz'altro più
fortuna. :-)
Max


 GetWindowText(GetDlgItem(hdrMezz, ID_DM), caratt.begin, 20);
GetWindowText(GetDlgItem(hdrMezz, ID_DM), caratt.begin(), 20);
begin() è un metodo. Se non ci metti le parentesi cerchi di passare un
puntatore a funzione invece del valore restituito dalla chiamata ad
esso.
EMG

EMG
Giacomo

 un char* usabile ai tuoi fini...), 
Sei sicuro che vector::begin() sia tenuto a restituire
un puntatore?
Da quello che mi risulta,  &v[0]  e' garantito al 100%,
mentre begin() restituisce un vector::iterator, che
potrebbe _non_ essere un puntatore, quindi non e' garantito,
anche se in molte implementazioni potrebbe funzionare.
	Mauro

 const' to 'char *'
Mi sfugge l'esatto perche` del tipo a cui ha scelto di risolvere
la begin (perche` l'overload const invece che l'altro? secondo
me dovrebbe dare un errore di ambiguita` di overload), comunque
il problema non e` certo questo, bensi` il fatto che la funzione
tu DEVI CHIAMARLA, e non lo stai facendo.
Alex

 Qual'è la differenza tra begin e pushback?
Qual'e` la differenza fra Verdi e la pastasciutta?  Se non e` per
fare una battuta, la domanda e` mal posta, poiche` chiede "la"
differenza fra entita` che di differenze ne hanno tantissime; si
fa prima a dire cosa hanno in comune (molto poco: nel caso di
Verdi e pastasciutta, solo il fatto di essere due entita` per cui l'Italia
e` giustamente famosa; nel caso di begin e pushback, solo il fatto
di essere due nomi di metodi esposti da molti dei contenitori
standard del C++).
Alex

 anche se in molte implementazioni potrebbe funzionare.
Lo standard, nel testo approvato dai comitati, era ambiguo
su questo punto fondamentale.  Bjarne Stroustrup ha poi
presentato un "defect report" relativo a questa ambiguita`
dello standard, che il comitato di "manutenzione" dello
standard ha approvato: la INTENZIONE dei comitati era
di offrire questa garanzia, era invece la ESPRESSIONE di
questa intenzione nello standard ad essere difettosa, ed
il difetto e` ora stato corretto.
Purtroppo, non so dove si possa reperire l'elenco di tutti
i defect report (sia quelli ancora aperti, sia quelli risolti, e
con quale risoluzione), e neppure (che io sappia) la copia
dello standard che viene venduta dalle varie organizzazioni
di standardizzazione (sia in-linea, sia in forma cartacea)
contiene tutte le correzioni previste dai defect report
accettati e risolti.
L'unica, che io sappia, e` frequentare comp.std.c++ per
tenersi aggiornati in merito.
NB: sia v.begin(), sia &v[0], funzioneranno correttamente
solo per un vettore v NON VUOTO.  Se v e` vuoto, &v[0]
puo` causare undefined behaviour, v.begin() no, ma cio`
che torna (eguale a v.end()) puo` non essere usabile.
Non capisco appieno il perche` di questa "violazione" alla
semantica C++ (dove, in generale, SI PUO` prendere
l'indirizzo del "primo elemento NON esistente" di un array,
basta non DEREFERENZIARE quell'indirizzo), ma penso sia
connessa alle problematiche di efficienza di std::vector e
al fatto che, a differenza dei vector, gli array non possono
essere "vuoti" (zero elementi).
Alex

 Qual'è la differenza tra begin e pushback?
Sostanziale: begin() restituisce l'iteratore alla sua prima posizione
mentre push_back() (non pushback()) aggiunge un nuovo elemento in coda
al vettore.
EMG