web-dev-qa-db-fra.com

Comment diviser une chaîne en 2 chaînes en C

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.

38
Mark Szymanski
#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);

Mise à jour

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);
}
56
ereOn

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.

11
Sparky
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.

3
N 1.1

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;
}
3
mkafkas

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," "));
1
fnisi

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.

1
Mehrdad Afshari

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'

1
Brian R. Bondy

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.

1
codaddict