2017-10-19 8 views
0

Pourquoi une erreur de segmentation se produit-elle après la lecture d'un seul mot?Comment séparer le délimiteur de mot d'entrée de l'utilisateur en espace en utilisant strtok

Si j'entre « pourquoi est-ce fonctionne pas »

Je ne reçoivent que

pourquoi

puis je reçois une erreur de segmentation.

J'ai vu d'autres exemples, mais aucun n'a utilisé l'entrée utilisateur comme je suis en train de faire ici. Je ne peux lire qu'un mot et ça ne marchera pas. J'ai essayé de changer tous les% c en% s mais ça ne m'aide pas. Je me rends compte également que le défaut de segmentation est pointeur pointant vers quelque part pas en mémoire mais je ne peux pas voir ce qui ne va pas avec lui. S'il vous plaît aidez-moi à comprendre.

#include <stdio.h> 
#include <string.h> 

int main() 
{ 
    char word[100]; 

    printf("Enter a sentence: "); 
    scanf("%s", word); 

    char *tok = strtok(word, " "); 
    printf("%s\n", tok); 

    while(tok != NULL) 
    { 
     tok = strtok(NULL, " "); 
     printf("%s\n", tok); 

     if(tok == NULL) 
      printf("finished\n"); 
    } 

    return 0; 
} 

EDIT: J'ai modifié scanf ("% s", mot); à fgets (mot, 100, stdin); et maintenant il imprime tout mais je reçois une erreur de segmentation.

+1

'scanf ("% s ", mot);' ne sauvegarde pas les espaces dans 'word', seulement' "why" '. Utilisez 'fgets()'. – chux

+0

@chux merci mec je l'ai changé en fgets (mot, 100, stdin) mais je reçois toujours la faute de segmentation. – Anonymous

+1

Indice: Pourquoi le code fait-il 'printf ("% s \ n ", tok);' et _then_ vérifie-t-il si '(tok == NULL) ...'? – chux

Répondre

2

Comme indiqué dans les commentaires, il y a au moins deux problèmes dans votre premier code.

  1. Ne pas utiliser scanf pour lire une chaîne que vous souhaitez analyser. Utilisez fgets à la place.

  2. Vous ne tester que tok n'est pas NULL avant de l'utiliser (dans la boucle while)

Ces problèmes auraient été facilement détectés avec le débogage, donc je vous invite à lire how to debug small programs

code corrigé doit être comme:

#include <stdio.h> 
#include <string.h> 

int main(void) 
{ 
    char word[100]; 

    printf("Enter a sentence: "); 
    /* read from stdin 
     note the `sizeof char`, if you need to change the size of `word`, 
     you won't have to change this line. */ 
    fgets(word, sizeof word, stdin); 

    /* initialize parser */ 
    char *tok = strtok(word, " "); 

    while (tok != NULL) 
    { 
     /* printf token: it cannot be NULL here */ 
     printf("%s\n", tok); 

     /* get next token*/ 
     tok = strtok(NULL, " "); 
    } 
    printf("finished\n"); 

    return 0; 
} 
+1

Suggérer de déclarer 'char * delim =" \ n ";' et ensuite 'char * tok = strtok (mot, delim);' (avec des changements similaires en utilisant 'delim' tout au long). –

0

Ce code est incorrect

while(tok != NULL) 
{ 
    tok = strtok(NULL, " "); 
    printf("%s\n", tok); 

    if(tok == NULL) 
     printf("finished\n"); 
} 

Supposons que vous obtenez à la dernière passe à travers la boucle .... il pénètre dans la boucle que vous avez la dernière fois .... alors vous faites une tok = strtok(NULL, " "); qui retourne (et ayants droit) NULL comme il est pas plus de choses .... alors vous printf(3), ce qui a produit la faute de seg.

il suffit de changer cela en cela, afin que vous ne tombiez pas dans la boucle il n'y a plus de jetons sont disponibles.

while((tok = strtok(NULL, " ")) != NULL) 
{ 
    printf("%s\n", tok); 

    /* you don't touch tok inside the loop, so you don't need to 
    * test it again once you get inside */ 
} 

/* if(tok == NULL) <-- you always have tok == NULL here */ 
printf("finished\n"); 

ou plus simple

while(tok = strtok(NULL, " ")) 
{ 
    printf("%s\n", tok); 
} 
printf("finished\n"); 

En outre, ajouter \n au second paramètre de strtok(3) appel (dans les deux appels que vous avez dans votre liste, que vous ne pouvez avoir qu'un seul jeton et la dernière ligne fin doit radiées du premier appel), comme lorsque vous utilisez fgets(3) vous normalement obtenir un \n à la fin de la chaîne (que vous ne voulez pas):

char *tok = strtok(word, " \n"); 
printf("%s\n", tok); 

while(tok = strtok(NULL, " \n")) 
{ 
    printf("%s\n", tok); 
} 
printf("finished\n");