2016-08-19 1 views
1

Je vais essayer d'analyser une ligne dans ce format:strtok() NULL de retour au milieu de l'analyse syntaxique

1: 2,3,4,5,6,7,8,9,10 

si Im en utilisant la fonction strtok() avec 2 délimiteurs et , (espace et virgule) Mais pour une raison quelconque, quand j'arriverai à 6, la fonction retournera NULL.

fileName = strtok(line, spaceToken); 
fileName[strlen(fileName) - 1] = 0; //remove the ':' 
... 
//doing something with fileName 
... 
fileName = strtok(NULL, commaToken); 
while (fileName != NULL) <-----THE PROBLEM 
    ... 
    //doing something with fileName 
    fileName = strtok(NULL, commaToken); 
} 

Ainsi, lorsque le fichier sera 6, je me NULL.

Avec cette entrée:

file1: file2,file3,file4 

Où je me file2 pour pourrais-le fileName je reçois 'fil', et la prochaine itération sera NULL.

Ceci est le code complet si elle est aider

#include <stdio.h> 
#include <memory.h> 

#define MAX_LINE_NUMBER 11 
#define MAX_FILE_NAME_NUMER 255 
#define MAX_FILES 10 

//function declaration 
void parseFile(char path[]); 

int contain(char fileName[]); 

int addToDependencieArray(char fileName[], int currentFileIndex); 

enum COLOR 
{ 
    WHITE, GRAY, BLACK 
}; 

typedef struct MyFile 
{ 
    char name[MAX_FILE_NAME_NUMER]; 
    int neighbors[MAX_FILES]; 
    int neighborsCounter; 
    enum COLOR myColor; 
    int predecessor; 
} MyFile; 


//global 
MyFile gDependencies[MAX_FILES]; 
int gCurrentFilesWriten = 0; 

int main(int argc, char *argv[]) 
{ 
    parseFile(argv[1]); 
    puts("hello"); 
} 

void parseFile(char path[]) 
{ 

    FILE *fPointer = fopen(path, "r"); 
    char line[MAX_LINE_NUMBER]; 
    char spaceToken[2] = " "; 
    char commaToken[2] = ","; 
    char *fileName; 
    int currentFileIndex = 0; 
    int sourseFile = 0; 
    while (fgets(line, sizeof(line), fPointer)) 
    { 
     fileName = strtok(line, spaceToken); 
     fileName[strlen(fileName) - 1] = 0; //remove the : 
     int sourse = contain(fileName); 
     if (sourse == -1) // isn't contains 
     {// to create function add. 
      currentFileIndex = addToDependencieArray(fileName, currentFileIndex); 
      sourseFile = currentFileIndex - 1; 
     } 
     else // contain 
     { 
      sourseFile = sourse; 
     } 
     fileName = strtok(NULL, commaToken); 

     while (fileName != NULL) 
     { 
      if (contain(fileName) == -1) 
      { 
       currentFileIndex = addToDependencieArray(fileName, currentFileIndex); 
       int neighborIndex = gDependencies[sourseFile].neighborsCounter; 
       gDependencies[sourseFile].neighbors[neighborIndex] = currentFileIndex - 1; 
       gDependencies[sourseFile].neighborsCounter++; 
      } 
      fileName = strtok(NULL, commaToken); 
     } 

    } 
    fclose(fPointer); 
} 

int contain(char fileName[]) 
{ 
    int res = -1; 
    for (int i = 0; i < gCurrentFilesWriten; i++) 
    { 
     if (!strcmp(fileName, gDependencies[i].name)) 
     { 
      return i; 
     } 
     else 
     { 
      i++; 
     } 
    } 
    return res; 
} 

int addToDependencieArray(char fileName[], int currentFileIndex) 
{ 
    strcpy(gDependencies[currentFileIndex].name, fileName); 
    gCurrentFilesWriten++; 
    gDependencies[currentFileIndex].neighborsCounter = 0; 
    currentFileIndex++; 
    return currentFileIndex; 
} 
+0

'fileName [strlen (fileName) - 1] = 0; 'Note: strlen() peut retourner zéro. (et le nom de fichier pourrait même être NULL dans ce cas) – joop

+0

Merci, mais je peux supposer qu'il n'y aura pas de ligne vide. – limitless

+0

Pourquoi ne pas écrire un petit programme principal avec des données codées en dur au lieu de supposer que les choses sont "ok"? – PaulMcKenzie

Répondre

2
#define MAX_LINE_NUMBER 11 
... 
char line[MAX_LINE_NUMBER]; 
... 
while (fgets(line, sizeof(line), fPointer)) 

Vous lisez seulement les 11 premiers caractères de la ligne! Augmentez MAX_LINE_NUMBERet renommez-le à quelque chose comme MAX_LINE_LENGTH et cela devrait fonctionner.

Explication: when reading using fgets,

fgets() lit au plus un moins de taille caractères de flux

Vos exemples:

123456789a|bcdef <-- character number - fgets only reads through _a_ 
1: 2,3,4,5|,6,7,8,9,10 <-- 5 is the last thing you read 
file1: fil|e2,file3,file4 <-- "fil" is the end of the string 
+0

Merci, j'essaie de comprendre cela avec le débogueur pour 3 heures! MERCI – limitless

+1

:) Content de vous aider! – cxw

+0

@limitless qu'avez-vous réellement débogué? Regarder la variable 'line' pendant une seconde devrait suffire à comprendre, que le problème est arrivé avant le premier' strtok'. – grek40