Newsgroup: it.comp.lang.c++
Titolo: Da string[] a char**

Salve,
ho una funzione in C che accetta come parametro un array di stringhe, 
char**. Io però, sfortunatamente, ho a disposizione solo array di 
stringhe in stile c++, string[].
c_str non viene in mio aiuto, in quanto su un array non è usabile 
(ovviamente). Se avessi una semplice stringa potrei fare anche così:
string omg("hello, world");
char* tmp = &omg[0];
ma, nel caso di un array di stringhe, non saprei come comportarmi con 
questo approccio, né se sia usabile.
Forse
items = sizeof(mystring)/sizeof(string);
char** b;
b = new char[items][MAXLENGTH];
//poi creare tutte le stringhe con c_str, in modo da avere una copia 
esatta della string[] in stato di char**
solo che, oltre a non funzionare[1], è anche un problema per MAXLENGTH, 
che per trovarla dovrei ciclare tutto l'array alla ricerca della stringa 
più lunga.
Provando invece
char** b = &mystring[0];
ricevo questo errore:
test.cpp:17: error: cannot convert ‘std::string*’ to ‘char**’ in assignment
C'è un modo abbastanza pulito per farlo? Ho l'impressione di perdermi in 
un bicchier d'acqua...
Grazie in anticipo ^^
Marco
[1] l'errore che ricevo è questo, e non lo capisco. Cos'è che va 
indigesto al compilatore? Sono due puntatori a puntatori di caratteri...
test.cpp: In function ‘int main(int, char**)’:
test.cpp:17: error: cannot convert ‘char (*)[15]’ to ‘char**’ in assignment

 test.cpp:17: error: cannot convert ‘char (*)[15]’ to ‘char**’ in assignment
questo è un array di quindici elementi, ciascuno dei quali è 
un puntatore a carattere.
Ora non ricordo bene, ma FORSE, togliendo il 15 (la 
dimensione fissa) nella dichiarazione del prototipo, un 
array di dimensione indefinita collassa automaticamente a 
puntatore al primo elemento. Ma sono un po' arrugginito :-(
P.S. quando sai esattamente cosa fai, a volte con un cast 
a-là C o uno static_cast, si riesce a forzare la mano in 
queste conversioni.
Il punto è che non so cosa ritornino gli operatori & 
(address of) applicati ad un oggetto di classe string.
Devi verificare nella libreria stantard se ritorna 
l'indirizzo fisico dell'oggetto istanziato o al "contenuto". 
Nel primo caso, a te non servirebbe a nulla.
ciao
Soviet

 Soviet
Ciao soviet, grazie per la risposta!
Allora, tanto vale raccontare tutta la storia, perché i dubbi che hai tu 
sono gli stessi che ho io, e a questo punto meglio avere chiara la 
situazione, e fin'ora sono stato un po' approssimativo.
Dai un occhio a questo esempio
http://sprunge.us/ISfK?cpp
la funzione in questine è questa
int sqlite3_prepare_v2(
   sqlite3 *db,            /* Database handle */
   const char *zSql,       /* SQL statement, UTF-8 encoded */
   int nByte,              /* Maximum length of zSql in bytes. */
   sqlite3_stmt **ppStmt,  /* OUT: Statement handle */
   const char **pzTail     /* OUT: Pointer to unused portion of zSql */
);
sto lavorando con un db sqlite3 (come credo si sia capito ^^), 
nell'esempio uso una semplice matrice di stringhe (che però ne contiene 
una sola, visto che la query è una), e quello che vorrei fare è usare al 
suo posto un oggetto string (perché è con quello che lavoro in tutto il 
resto dell'applicazione, di cui il db è solo una parte).
[nota: ometto il prefisso sqlite3_ delle funzioni per brevità]
Funzinoa così, si passa a prepare_v2 un'array di stringhe contenente le 
varie query, dopodiché la funzione step() le esegue una per una e 
permette di accedere ai risultati tramite altre funzioni per accedere 
alle risposte del db (come column_count() ).
L'oggetto sqlite3_stmt contiene le risposte del db, che vanno fetchate 
con le sovracitate funzioni di navigazione di ciò che la query ritorna.
Questo solo per chiarire le cose, perché sto scappando via ;)
Marco

 varie query,
Credo ti stia confondendo, si passa un char*, una singola stringa 
("const char *zSql")


 
io non so NIENTE, ma proprio zero, di SQL ...
Però vedo che nei commenti di aiuto di documentazione, quei 
parametri incriminati sono spiegati come "OUT"
Questo mi fa pensare che la funzione voglia SETTARLI dentro 
e passarli fuori come valori di ritorno.
Praticamente è come voler passare una REFERENCE (con vecchia 
sintassi C pre-reference) a una semplice stringa. Niente matrici
Come dire della tua query la funzione lascia una stringa 
ancora non elaborata (forse parte della tua query, non 
saprei) e ti vuole indicare dove. Quindi deve passarti una 
stringa FUORI dalla funzione, e per riferimento (così da 
essere veloce e non effettuare copie.
Allora ti chiede l'indirizzo di un oggetto char*, in altre 
parole un puntatore passato per riferimento.
Stessa cosa per quello handle, forse.
Tieni presente che mi son fatto questa idea solo leggendo i 
commenti, ma non so niente di sql
ciao
Soviet



Se può interessarti, qui ho messo un piccolo esempio. Spero ti sia utile:
http://antoniotancredi.altervista.org/2010/03/25/c-e-sqlite-primo-esempio/


Chiedo scusa a tutti per il tempo perso, ho preso un granchio enorme, 
sto facendo una specie di wrapper e tra diverse funzioni ho confuso 
l'uso delle semplici api di sqlite3. Mea maxima culpa... prende 
semplicemente una stringa, mi basta c_str.
Scusate ancora, e grazie per essere sempre disponibili
Marco

 
http://antoniotancredi.altervista.org/2010/03/25/c-e-sqlite-primo-esempio/
Molto! Grazie mille ^^

 
http://antoniotancredi.altervista.org/2010/03/25/c-e-sqlite-primo-esempio/
C'ï¿½ perï¿½ un errore abbastanza subdolo nell'esempio:
char* errMsg = new char(1024);
...
delete errMsg;
Cosï¿½ allochi dinamicamente *un* char e lo inizializzi col valore 1024 
(cosa che provoca un overflow).
Se vuoi allocare un array di char devi scrivere:
char* errMsg = new char[1024];
...
delete[] errMsg;
Ciao.

 Ciao.
Cavolo, mi spiace, ero di fretta e l'esempio l'ho scritto di getto per 
postarlo subito. Vi assicuro che di solito so come allocare un array :P
Grazie per la segnalazione!