2012-12-25 3 views
-5

J'ai essayé d'écrire une fonction qui obtient un pointeur vers un tableau de char, lit une chaîne de l'utilisateur et supprime tous les espaces au début de la chaîne jusqu'à ce que le premier caractère qui n'apparaît pas. Enfin, retournez la copie de la chaîne sans espace/s au début.strtok ne fonctionnait pas comme prévu

Par exemple,

pour l'entrée abcd la fonction doit retourner un pointeur vers la chaîne abcd.

pour l'entrée 123 123 la fonction doit renvoyer le pointeur vers la chaîne 123 123.

La fonction est indiquée ci-dessous,

void read_RemoveSpace(char * str)/**read the rest of string**/ 
{ 
    char tempRead[30]; 
    fgets(tempRead,30,stdin); 
    char *ptr = strtok(tempRead, " "); /**remove spaces between command and other data**/ 
    strcpy(str,ptr); /**copy the new string without the spaces.**/ 
} 

Mais une raison strtok() la fonction ne fonctionne pas comme prévu.

En cas d'entrée:

123 456 

la fonction retourne que la première partie sans les espaces, mais pas le reste de la chaîne, à savoir qu'il pointe vers

123 

Toutes les suggestions?

+0

Et votre ** question ** !? – StoryTeller

+0

Quel est le problème auquel vous faites face? Comment appelez-vous la fonction? Qu'est-ce qui est exactement stocké dans str après l'appel? – Vijay

+0

'strtok_r()' fonctionne comme prévu, peut-être que vos attentes sont incorrectes ... –

Répondre

4

strtok fonctionne exactement comme prévu. Il casse l'entrée dans les chaînes 123 et 456.

strtok (tempRead, " "); /* Returns 123 */ 
strtok (NULL, " "); /* Returns 456 */ 

Je pense que vous pouvez faire avec une solution plus simple:

int i = 0; 
char tempRead[30]; 
... 
while (tempRead[i] == ' ' && tempRead[i]) 
    i++; 
strcpy(str,tempRead+i); 
2

Il fonctionne exactement comme prévu.

Le premier appel à strtok renvoie la première occurrence du jeton; les appels suivants renvoient le reste des jetons un à la fois tant que vous fournissez le premier paramètre comme NULL; et strtok retournera NULL quand il n'aura plus de jetons.

EDIT:
Certaines choses pourraient entraîner des bugs étranges, donc je cite ici ce que les pages de manuel mentionnent et ce que vous devez toujours garder à l'esprit lorsque vous utilisez strtok:

Soyez prudent lorsque vous utilisez ces fonctions. Si vous les utilisez, notez que :

  • Ces fonctions modifient leur premier argument.

  • Ces fonctions ne peuvent pas être utilisées sur des chaînes constantes.

  • L'identité du caractère de délimitation est perdue.

  • La fonction strtok() utilise un tampon statique lors de l'analyse, donc ce n'est pas thread sûr. Utilisez strtok_r() si cela vous intéresse.

0

L'utilisation strtok() n'est pas la façon évidente de le faire.

void read_RemoveSpace(char *str) 
{ 
    char *dst = str; 
    char tempRead[30]; 
    if (fgets(tempRead, sizeof(tempRead), stdin) != 0) 
    { 
     char *src = tempRead; 
     char c; 
     while ((c = *src++) != '\0') 
     { 
      if (c != ' ') 
       *dst++ = c; 
     } 
    } 
    *dst = '\0'; 
} 

Cette copie les non-blancs dans tempRead en str, y compris une nouvelle ligne; vous pouvez utiliser isspace() ou isblank() de #include <ctype.h> si vous préférez. Je ne suis pas convaincu que 30 est une bonne longueur pour la chaîne locale, mais c'est ce que vous aviez dans la question. Vous pouvez sans doute spécifier la taille d'une chaîne dans l'interface: void *read_RemoveSpace(char *buffer, size_t buflen). Vous pourriez également utilement avoir la fonction retourner le pointeur à la null à la fin de la chaîne (donnant ainsi indirectement la longueur de la chaîne moins les blancs).

void read_RemoveSpace(char *buffer, size_t buflen) 
{ 
    char *dst = buffer; 
    char tempRead[buflen]; 
    if (fgets(tempRead, sizeof(tempRead), stdin) != 0) 
    { 
     char *src = tempRead; 
     char c; 
     while ((c = *src++) != '\0') 
     { 
      if (!isspace((unsigned char)c)) 
       *dst++ = c; 
     } 
    } 
    *dst = '\0'; 
    return dst; 
} 

Pas très différent, mais beaucoup plus sûr. Il utilise un tableau local VLA - variable length - qui fait partie de C99. Il serait possible de renoncer à la VLA et faire la copie dans le tampon cible directement:

void read_RemoveSpace(char *buffer, size_t buflen) 
{ 
    char *dst = buffer; 
    if (fgets(buffer, buflen, stdin) != 0) 
    { 
     char *src = buffer; 
     char c; 
     while ((c = *src++) != '\0') 
     { 
      if (!isspace((unsigned char)c)) 
       *dst++ = c; 
     } 
    } 
    *dst = '\0'; 
    return dst; 
} 

Jusqu'au premier espace blanc, cette copie est un no-op; par la suite, il copie les caractères dans leur position finale.

Questions connexes