2017-10-01 3 views
0

Donc j'essaye de lire un fichier qui est une série de mots et de phrases séparés par | et séparez-les par strtok() en plaçant les jetons dans un tableau. Ensuite, imprimez le tableau juste pour vérifier si le contenu est correct.
Cependant, la sortie est incorrecte.
Voici mon code.C - lire le fichier et le scinder avec strtok dans un tableau

#include <stdlib.h> 
#include <stdio.h> 
#include <string.h> 
int main(int argc, char ** argv) 
{ 
    FILE *fp; 
    char *str=malloc(80*sizeof(char)); 
    int count=0; 
    char *tokenArray[100]; 
    int i=0; 
    int j=0; 
    char *token = strtok(str, "|"); 

    printf("Loading stock...\n"); 
    fp = fopen(argv[1], "r"); 
    while(fgets(str, sizeof(str),fp)!=NULL){   
     tokenArray[0]=strtok(str,"|"); 

     for(i=1; i<200; i++){ 
      if((tokenArray[i]=strtok(NULL,"|")) ==NULL) 
       break; 
     } 
     count=i; 

     for(i=0; i<count;i++){ 
      printf("%d: %s\n",i,tokenArray[i]); 
     } 
    } 
    return EXIT_SUCCESS; 
} 

Quels sont les résultats à la sortie:

Loading stock... 
0: I0001 
1: M 
0: eat Pie 
0: Yummy 
0: Beef in 
0: Gravy 
0: surroun 
0: ded by 
0: pastry 
0: 3.50 
1: 50 
0: 

0: I0002 
1: A 
0: pple Pi 
0: e 
1: Delic 
0: ious St 
0: ewed Ap 
0: ple in 
0: a Yummy 
0: Pastry 
0: envelo 
0: pe 
1: 3.00 
0: 20 

Ce qui est pas grande. Toutefois, si je tweak si str est statique char str[80]; il fonctionne et la sortie est

0: I0001 
1: Meat Pie 
2: Yummy Beef in Gravy surrounded by pastry 
3: 3.50 
4: 50 

Mais pour l'amour de ma mission, je doit utiliser malloc(). Qu'est-ce qui ne va pas?

+2

Le premier 'char * jeton = strtok (str , "|"); 'est avant que' str' ait des données. –

+1

Ceci: 'for (i = 1; i <200; i ++)' est également inquiétant, puisque les index de tableau commencent à 0, et l'index maximum valide pour 'tokenArray' est 99. –

+1

Comme vous lisez dans chaque ligne, vous écrasez la ligne précédente. Ainsi, les pointeurs que vous avez stockés ne pointent plus vers les jetons que vous imaginez. Vous devez allouer de la mémoire pour chaque token et le copier. –

Répondre

1

Veuillez voir la version corrigée de votre code avec les commentaires en ligne. Votre problème principal était l'interprétation incorrecte de sizeof(str) (et cela, en fait, explique pourquoi cela fonctionnait quand str était un tableau de caractères au lieu d'un pointeur), mais j'ai également corrigé certains des problèmes mentionnés dans les commentaires sur la question initiale. En outre, vous voudrez peut-être étudier comment fonctionne réellement strtok() si vous avez plusieurs lignes qui ont besoin de tokenizing - comme mentionné par Weather Vane, car il ne fonctionnera pas avec plusieurs lignes si vous voulez conserver les anciens jetons. Je vais laisser la solution appropriée à cette question comme un exercice pour le PO si c'est ce que la mission demande.

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

#define BUF_SIZE 80 

int main(int argc, char ** argv) 
{ 
    FILE *fp; 
    char *str=malloc(BUF_SIZE*sizeof(char)); 
    int count=0; 
    char *tokenArray[100]; 
    int i=0; 
    int j=0; 
    // See comment by Weather Vane 
    //char *token = strtok(str, "|"); 
    char *token; 

    printf("Loading stock...\n"); 
    fp = fopen(argv[1], "r"); 
    // sizeof(str) == sizeof(char *) == 8 on x86_64, NOT 80 as you assumed 
    //while(fgets(str, sizeof(str),fp)!=NULL){ 
    while(fgets(str, BUF_SIZE, fp)!=NULL){ 

     tokenArray[0]=strtok(str,"|"); 

     // See comment by Martin James about array bounds 
     //for(i=1; i<200; i++){ 
     for(i=1; i < sizeof(tokenArray)/sizeof(tokenArray[0]); i++){ 
      if((tokenArray[i]=strtok(NULL,"|")) ==NULL) 
       break; 
     } 
     count=i; 

     for(i=0; i<count;i++){ 
      printf("%d: %s\n",i,tokenArray[i]); 
     } 
    } 
    return EXIT_SUCCESS; 
} 

fonctionne très bien si test.txt contient:

I0001|Meat Pie|Yummy Beef in Gravy surrounded by pastry|3.50|50 

Et est appelé:

$./tmp test.txt 

Sortie:

Loading stock... 
0: I0001 
1: Meat Pie 
2: Yummy Beef in Gravy surrounded by pastry 
3: 3.50 
4: 50