PDA

Visualizza la versione completa : [c++]suddividere una stringa in token


ramy89
26-12-2011, 18:25
Voglio suddividere una stringa in token in modo che se alcuni caratteri sono ripetuti, quella parte della stringa viene tagliata e messa in una stringa a parte.
Per chiarirmi faccio un esempio, ho la stringa "aaccbb", allora divido la stringa in 3 stringhe:
"aa" "bb" e "cc".
Per questo mi serve di avere un puntatore a puntatore di char (potrei anche avere tanti string ma lo sto risolvendo così),e allocare una nuova stringa ogni volta che la sequenza di caratteri uguali finisce.


char **getTokens(char *s, int *n)
{
unsigned int i=1,counter=1,j;
char current=s[0];
char **temp;
temp=new char *[100];
*n=0;
while(i<strlen(s))
{
if(current==s[i])
{
i++;
counter++;
}
else
{
cout <<*n <<endl;
temp[*n]=new char[counter+1]; // segmentation fault
for(j=i-counter;j<=i;j++)
temp[*n][j]=s[j];
i++;
counter=0;
*n++;
}
}
return temp;
}

Se uso questa funzione su di una stringa va in segmentation fault alla riga che ho segnato e non capisco il perchè.
Io ho allocato il puntatore a puntatore, per sicurezza gli ho dato 100 elementi.
Se ogni elemento è un puntatore,quando dichiaro :


temp[0]=new char[counter+1];

Non dovrebbe andare in segmentation fault perchè temp[0] è già stato allocato, qual'è il problema?

oregon
26-12-2011, 18:27
Prima di tutto dovrebbe essere

(*n)++;

SamIam
26-12-2011, 20:33
Il problema scaturiva nell'uso improprio di alcuni indici e da come venivano gestiti i terminatori, credo :zizi:


char **getTokens(char *s, int *n)
{
unsigned int i=0, q=0, j;
char current = s[0];
char **temp = new char* [100];
*n=0;
while( 1 )
{
if( s[i] == NULL || current != s[i] )
{
current = s[i];
temp[*n] = new char [(i-q)+1];
for( j=0; j<i-q; j++)
temp[*n][j] = s[q+j];
temp[*n][i-q] = NULL;
q=i;
(*n)++;
if( s[i] == NULL )
return temp;
}
i++;
}
}

ramy89
26-12-2011, 22:00
L' ho comunque voluta rifare con un approcio diverso: fare un array contenente tutti gli indici in corrispondenza ai quali la stringa va separata (es: se ho "IICCXX" gli indici saranno 0,2,4,6), e poi allocare le varie stringhe da restituire scrivendoci i valori copiati dal pezzo di stringa corrispondente:


char **getTokens(char *s, int *n)
{
char **tokens;
int **indexes,s1,s2,j;
*n=0;
tokens=new char *[100];
indexes=new int *[100];
indexes[0]=new int;
indexes[0][0]=0;
for(int i=0;i<(int)strlen(s)-1;i++)
{
if(s[i]!=s[i+1])
{
(*n)++;
indexes[*n]=new int;
indexes[*n][0]=i+1;
}
}
(*n)++;
indexes[*n]=new int;
indexes[*n][0]=strlen(s);
for(int i=0;i<*n;i++)
{
j=0;
s1=indexes[i][0];
s2=indexes[i+1][0];
tokens[i]=new char[s2-s1];
for(int k=s1;k<s2;k++)
{
tokens[i][j]=s[k];
j++;
}
}
return tokens;
}

Quella corretta da te comunque da dei warnings, e non mi piace il valore di ritorno il mezzo alla funzione, ne il while(1).

Loading