Je me demandais comment prendre une chaîne, la scinder en 2 avec un délimiteur, tel que l'espace, et affecter les 2 parties à 2 chaînes distinctes. J'ai essayé d'utiliser strtok()
mais en vain.
#include <string.h>
char *token;
char line[] = "SEVERAL WORDS";
char *search = " ";
// Token will point to "SEVERAL".
token = strtok(line, search);
// Token will point to "WORDS".
token = strtok(NULL, search);
Notez que sur certains systèmes d’exploitation, la page de manuel strtok
mentionne:
Cette interface est obsolète par strsep (3).
Un exemple avec strsep
est présenté ci-dessous:
char* token;
char* string;
char* tofree;
string = strdup("abc,def,ghi");
if (string != NULL) {
tofree = string;
while ((token = strsep(&string, ",")) != NULL)
{
printf("%s\n", token);
}
free(tofree);
}
Pour de telles raisons, j'ai tendance à utiliser strtok_r () au lieu de strtok ().
Par exemple ...
int main (void) {
char str[128];
char *ptr;
strcpy (str, "123456 789asdf");
strtok_r (str, " ", &ptr);
printf ("'%s' '%s'\n", str, ptr);
return 0;
}
Cela va sortir ...
'123456' '789asdf'
Si davantage de délimiteurs sont nécessaires, bouclez.
J'espère que cela t'aides.
char *line = strdup("user name"); // don't do char *line = "user name"; see Note
char *first_part = strtok(line, " "); //first_part points to "user"
char *sec_part = strtok(NULL, " "); //sec_part points to "name"
Remarque: strtok
modifie la chaîne, ne lui attribuez donc pas un pointeur sur la chaîne.
Vous pouvez utiliser strtok () pour cet exemple: cela fonctionne pour moi
#include <stdio.h>
#include <string.h>
int main ()
{
char str[] ="- This, a sample string.";
char * pch;
printf ("Splitting string \"%s\" into tokens:\n",str);
pch = strtok (str," ,.-");
while (pch != NULL)
{
printf ("%s\n",pch);
pch = strtok (NULL, " ,.-");
}
return 0;
}
Voici comment vous implémentez une fonction de type strtok()
(tirée de ne bibliothèque de traitement de chaînes sous licence BSD pour C, appelée zString ).
La fonction ci-dessous diffère de la norme strtok()
par la façon dont elle reconnaît les délimiteurs consécutifs, alors que la norme strtok()
ne le fait pas.
char *zstring_strtok(char *str, const char *delim) {
static char *static_str=0; /* var to store last address */
int index=0, strlength=0; /* integers for indexes */
int found = 0; /* check if delim is found */
/* delimiter cannot be NULL
* if no more char left, return NULL as well
*/
if (delim==0 || (str == 0 && static_str == 0))
return 0;
if (str == 0)
str = static_str;
/* get length of string */
while(str[strlength])
strlength++;
/* find the first occurance of delim */
for (index=0;index<strlength;index++)
if (str[index]==delim[0]) {
found=1;
break;
}
/* if delim is not contained in str, return str */
if (!found) {
static_str = 0;
return str;
}
/* check for consecutive delimiters
*if first char is delim, return delim
*/
if (str[0]==delim[0]) {
static_str = (str + 1);
return (char *)delim;
}
/* terminate the string
* this assignmetn requires char[], so str has to
* be char[] rather than *char
*/
str[index] = '\0';
/* save the rest of the string */
if ((str + index + 1)!=0)
static_str = (str + index + 1);
else
static_str = 0;
return str;
}
Vous trouverez ci-dessous un exemple de code illustrant l'utilisation
Example Usage
char str[] = "A,B,,,C";
printf("1 %s\n",zstring_strtok(s,","));
printf("2 %s\n",zstring_strtok(NULL,","));
printf("3 %s\n",zstring_strtok(NULL,","));
printf("4 %s\n",zstring_strtok(NULL,","));
printf("5 %s\n",zstring_strtok(NULL,","));
printf("6 %s\n",zstring_strtok(NULL,","));
Example Output
1 A
2 B
3 ,
4 ,
5 C
6 (null)
Vous pouvez même utiliser une boucle while (la fonction strtok()
de la bibliothèque standard donnerait le même résultat ici)
char s[]="some text here;
do {
printf("%s\n",zstring_strtok(s," "));
} while(zstring_strtok(NULL," "));
Si vous êtes prêt à modifier la chaîne d'origine, vous pouvez simplement remplacer le délimiteur par \0
. Le pointeur d'origine pointera sur la première chaîne et le pointeur sur le caractère situé après le séparateur pointera sur la deuxième chaîne. La bonne chose est que vous pouvez utiliser les deux pointeurs en même temps sans allouer de nouveaux tampons de chaîne.
Si vous avez un tableau de caractères alloué, vous pouvez simplement mettre un '\0'
où tu veux. Puis pointez un nouveau pointeur char * sur l’emplacement juste après le '\0'
.
Cela détruira votre chaîne d'origine bien que selon l'endroit où vous mettez le '\0'
Tu peux faire:
char str[] ="Stackoverflow Serverfault";
char piece1[20] = ""
,piece2[20] = "";
char * p;
p = strtok (str," "); // call the strtok with str as 1st arg for the 1st time.
if (p != NULL) // check if we got a token.
{
strcpy(piece1,p); // save the token.
p = strtok (NULL, " "); // subsequent call should have NULL as 1st arg.
if (p != NULL) // check if we got a token.
strcpy(piece2,p); // save the token.
}
printf("%s :: %s\n",piece1,piece2); // prints Stackoverflow :: Serverfault
Si vous prévoyez plus d'un jeton, mieux vaut appeler le deuxième appel et les appels suivants à strtok
dans une boucle while jusqu'à ce que la valeur de retour de strtok
devienne NULL
.