View Full Version : [c] malloc e strtok: costruire stringhe senza sapere quanto sono grandi
agosteeno
23-06-2011, 15:30
Salve a tutti, ho un problema che non so' come risolvere: In pratica ho una funzione che riceve una stringa. Questa contiene 3 sottostringhe che sono delimitate da un carattere particolare. Io voglio ottenere queste e metterle in stringhe allocate dinamicamente con una malloc. Il problema sta' nel fatto che a priori non posso sapere di quanto dover fare la malloc, perche' la dimensione la posso sapere solo dopo aver fatto la strtok. La soluzione che mi viene in mente sarebbe di usare un array di caratteri come tampone (so' quale e' la dimensione massima della stringa e quindi posso creare una cosa del genere: char buffer[MAXDIM]; ) calcolare la dimensione di quanto messo qua dentro e poi fare la malloc di conseguenza. Il fatto e' che mi sembra un po' macchinoso e forzato. Qualcuno ha un idea su come poter risolvere con un po' piu' di eleganza questo problema? Questo sarebbe il codice che farei io:
char *sorgente;
char *destinazione;
char *distanza;
char buffer[MAXDIM];
int i = 1;
char c;
strcpy(buffer, strtok(temp, ":"));
c = buffer[0];
while(c != '\0'){
i++;
}
sorgente = malloc(i * sizeof(char));
...
e cosi' via per il resto...
strtok() (http://www.cplusplus.com/reference/clibrary/cstring/strtok/)
A sequence of calls to this function split str into tokens, which are sequences of contiguous characters separated by any of the characters that are part of delimiters.
On a first call, the function expects a C string as argument for str, whose first character is used as the starting location to scan for tokens. In subsequent calls, the function expects a null pointer and uses the position right after the end of last token as the new starting location for scanning.
To determine the beginning and the end of a token, the function first scans from the starting location for the first character not contained in delimiters (which becomes the beginning of the token). And then scans starting from this beginning of the token for the first character contained in delimiters, which becomes the end of the token.
This end of the token is automatically replaced by a null-character by the function, and the beginning of the token is returned by the function.
Once the terminating null character of str has been found in a call to strtok, all subsequent calls to this function with a null pointer as the first argument return a null pointer.
Quindi nulla ti vieta di usare un strlen per capire quant'è lunga la sequenza di caratteri restituita da strtok.
maulattu
23-06-2011, 16:14
usa la strtok_r (*nix) oppure strtok_s (windows) se devi usare i thread.
e, come buona abitudine, usa strncpy; questo:
strcpy(buffer, strtok(temp, ":"));
è un inno al buffer overflow :)
agosteeno
23-06-2011, 16:20
Hai ragione, alla strlen non avevo pensato. Per quanto riguada gli altri suggerimenti non vi preoccupate, terro' le considerazioni opportune. Ciao e grazie mille :)
agosteeno
23-06-2011, 17:12
Giusto un'ultima cosa: se la stringa che arriva come parametro e' malformata (nel senso che non ha il formato previsto) la strcpy(buffer, strtok()) mi da' problemi. Per esempio, la mia stringa ha in generale questo formato:
abc:def:ghi
quindi farei 3 strtok, ma se per esempio trovo una stringa cosi':
abc:def:
la 3' operazione mi dara' problemi. Come potrei fare per controllare prima?
Guarda l'esempio di strtok contenuto nel link che ho postato poco fa; la strtok viene eseguita (a parte la prima volta) in un ciclo in cui ne viene controllato il valore restituito, confrontandolo con NULL.
agosteeno
23-06-2011, 18:12
grazie :)
vBulletin® v3.6.4, Copyright ©2000-2025, Jelsoft Enterprises Ltd.