Puntatori e allocazione dinamica

EISguys
Ciao a tutti,
avrei qualche domande circa l'utilizzo dei puntatori.

Il mio problema è di voler aprire in file del tipo "bck123.dat". Posso farlo con l'operazione ifstream in("bck123.dat") etc etc. E fin qui ci sono.
il fatto è che il nome del file da aprire viene prodotto da una funzione che ho creato io bck(n) che restituisce una variabile di tipo string appunto del tipo "bck(n).dat".
Ora per non posso usare ifstream in(path_in), dove path_in è di tipo string, perché ifstream vuole variabili di tipo char.

allora sto cercando di convertire la variabile di tipo string in char.

Per fare questo sto cercando di usare i puntatori. Riporto parte del codice che ho scritto:

        int length_1;
	char* path_in;

	int n=1;

	while (n<bck_finale+1)
	{
		length_1=bck(n).length();
		path_in=(char*)malloc(length_1*sizeof(char));
		
		for (int j=0; j<length_1; j++){
			path_in[j]=bck(n)[j];
		} 
		
		
		ifstream in(path_in);
             ...


se faccio in questo modo però e vado a vedere poi cosa stamperebbe path_in, questo sarebbe per i primi caratteri giusti e uguale a bck(n), ma con in coda una serie di caratteri che non c'entrano niente!
ho pensato che non allocassi abbastanza memoria...anche se non capisco perchè, visto che facendo sizeof(bck(n)[j]), questo è uguale a 1! allora ho provato a mettere, dentro malloc(length_1*10), ma stessa roba...anzi peggio.

Ho fatto un giretto su i vari forum, e qualcuno usava la funzione calloc. L'ho fatto anch'io allora. E ho visto che se faccio calloc(lenght_1, sizeof (char)), cmq mi scrive schifezze, ma se alloco più memoria >3, allora sembra funzionare correttamente.
Ho allora pensato che la differenza fondamentale fosse che calloc inizializza il puntatore a 0, mentre malloc no.

Ho allora provato a riutilizzare malloc inizializzando però il puntatore a 0, usando una funzione che ho letto sempre in giro sui forum...

memset(path_in, 0, length_1+1);

produce le scritte corrette però solo se scrivo lenght_1+ 1 (o più).

Insomma...come avrete capito, sono un tantinello confuso. Qualcuno può darmi una mano? vi prego di spiegare il più possibile in un linguaggio semplice...mi sono imbattuto in alcuni forum in cui non capivo nemmeno quello che dicevano!!
Perdonate inoltre l'ineleganza della mia programmazione, e non ditemi perciò (come forse sarebbe più ragionevole) di abbandonare il tipo string, anche perchè ormai ho scritto praticamente tutto il codice!!!! ad ogni modo sono ormai curioso di capire dove sbaglio!

Grazie
ciao ciao

Risposte
Ska1
Il tipo 'string' ha un simpatico metodo 'c_str()' che resituisce la stringa "c-style". Il problema che si evince dal tuo codice è che non conosci come sono fatte le stringhe in C. In C una stringa stampabile è semplicemente un array di char zero-terminato. 'zero-terminato' significa che il terminatore di stringa è quel carattere che ha valore 0, questo viene usato da tutte le funzioni che manipolano le stringhe stampabili per capire quando la stringa stessa finisce. Quindi se voglio rappresentare una stringa di lunghezza $l$ allora devo allocare spazio per $l+1$ caratteri, dato che l'ultimo è il terminatore di stringa. Ad esempio:
char *str = malloc(5 * sizeof(char));
strcpy(str, "ciao");
str[4] = '\0'; // Dato che ho usato 'malloc' devo scrivere in modo esplicito il terminatore


Quindi nel tuo caso, dovresti fare una cosa del genere:
string s = "mia stringa";
char *str;
// Facendo a mano
str = malloc(size(char) * (s.length() + 1));
for (int i = 0; i < s.length(); i++) str[i] = s[i];
s[s.length()] = '\0';
// Usando il metodo già fatto
str = s.c_str();

EISguys
Perfetto grazie!
alla fine ho optato infatti per il simpatico metodo 'c_str()' :) cmq grazie per la spiegazione! in effetti non avevo idea che una stringa fosse "zero-terminata". Non mi ero mai posto il problema, e la utilizzavo alla stregua di come la usavo programmando in Pascal!

Grazie di nuovo
ciao ciao

Rispondi
Per rispondere a questa discussione devi prima effettuare il login.