2009-09-10 4 views
0

J'écris un petit programme en C qui va lire les entrées de la console. Puis placez-le dans un tableau char. Après cela, j'ai besoin de diviser le tableau en mots. Je ne suis pas sûr de savoir comment faire cela. Jusqu'à présent, j'ai mis l'entrée dans un tableau char. J'ai besoin de savoir s'il y a un moyen de tokeniser basé sur un caractère vide. Ou d'autres suggestions sur la façon de gérer ce problème. Merci.C Programmation. Lire l'entrée et l'analyser en mots

échantillon:

entrée: ceci seulement un test

tableau: [t, h, i, s,, i, s, o, n, L, Y, A,, t , e, s, t, null]

Je voudrais obtenir un tableau String [ce, est, seulement, un, test, null]

main() { 

    char msg[50], ch; 
    int i = 0; 

    printf("***Reading words in your input*****\n\n"); 
    printf("Type something terminated by ENTER button\n"); 

    while ((ch = getchar()) != '\n') 
     msg[i++] = ch; 

    msg[i] = '\0'; 

    i = 0; 

    while (msg[i] != '\0') 
     putchar(msg[i++]); 
    printf("\n"); 

} 
+0

Pour les ressources sur le problème général des problèmes d'analyse syntaxique voir http://stackoverflow.com/questions/1669/apprendre à écrire un compilateur. – dmckee

Répondre

2

Oui, utilisez la fonction strtok:

char* token = strtok(msg, " "); 
while (token != NULL) { 
    printf("%s", token); 
    token = strtok(NULL, " "); 
} 
+0

Une chose à se méfier est que strtok() maintient un état statique, donc il n'est pas thread-safe. Utilisez strtok_r() si c'est un problème. –

+0

strtok() modifie la chaîne d'origine. Cela pourrait aussi être un problème. vous ne pouvez pas strtok() une chaîne littérale :) – pmg

+0

Si c'est vraiment un problème, vous pouvez juste 'strcopy' la chaîne d'origine. –

0

Si vous voulez lire tous les mots jusqu'à la fin du fichier (pas d'arrêt à la ligne), alors c'est plus simple:

#include <stdio.h> 
int main(){ 
    char b[999]; 
    while (scanf("%s",b)==1) 
     puts(b); 
    return 0; 
} 

La valeur de retour de scanf est le nombre de champs analysés avec succès, ou EOF. Whitespace sert à séparer les champs "% s", donc vous obtenez les jetons que vous voulez. Bien sûr, si vous lisez d'abord une ligne, vous pouvez toujours utiliser sscanf.

Si vous voulez accumuler un tableau de chaînes au lieu de simplement les traiter une par une ("puts (b)" ci-dessus), vous devrez vous salir les mains avec realloc, malloc, strcpy et strlen . Les tampons de taille fixe sont méchants de toute façon.

0

C n'a pas de chaînes dans le sens où vous utilisez le mot. C a des tableaux de caractères.

Si vous voulez un tableau de chaînes ... vous pouvez avoir quelque chose de similaire à un tableau de tableaux de caractères.

Mais chaque tableau a une taille prédéterminée, et vous ne pouvez pas ajouter plus de "chaînes" ou les rendre plus longues que l'espace disponible. L'autre option (au lieu de tableaux de tableaux de char) est d'utiliser des pointeurs et de la mémoire de malloc() et des amis (je laisserai la discussion des poonters, malloc() et des amis pour une autre fois).

Pour définir un tableau de tableau de char et de diviser une phrase par les espaces, vous pouvez le faire

char array_of_string[10][6]; /* 10 strings of a maximum of 5 characters each, plus the NUL */ 
char msg[50] = "this is a test"; 
/* now split the msg and put the words in array_of_string */ 
int string_num = 0; 
int word_size = 0; 
int msg_index = 0; 

while (msg[msg_index] != '\0') { 
    if (msg[msg_index] != ' ') { 
     /* add the character to the proper place in array_of_string */ 
     array_of_string[string_num][word_size] = msg[msg_index]; 
     /* and update word_size for next time through the loop */ 
     word_size++; /* needs check for reserved word size (5) */ 
    } else { 
     /* a space! */ 
     /* first, terminate the current word */ 
     array_of_string[string_num][word_size] = '\0'; 
     /* prepare to start the next word */ 
     string_num++; /* needs check for reserved number of "strings" (10) */ 
     word_size = 0; 
    } 
} 
/* array_of_string[0] is now "this" 
* array_of_string[1] is now "is" 
* ... 
*/