2016-08-19 1 views
1

Я пытаюсь разобрать строку в следующем формате:strtok() возвращает NULL в середине разборе

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

так Im используя функцию strtok() с 2 разделителями и , (пробел и запятая) Но по какой-то причине, когда я добираюсь до 6, funcion возвращает 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); 
} 

Так что, когда имя_файл должен быть 6, я получаю NULL.

С этим входом:

file1: file2,file3,file4 

Где я sould получить file2 для fileName я получаю 'fil', и следующая итерация будет NULL.

Это полный код, если это поможет

#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

'имя_файла [STRLEN (fileName) - 1] = 0; 'Примечание: strlen() может возвращать ноль. (и имя файла может даже быть NULL в этом случае) – joop

+0

Спасибо, но я могу предположить, что не будет никакой пустой строки. – limitless

+0

Почему бы не написать небольшую основную программу с жестко закодированными данными, а не предполагать, что вещи «хорошо»? – PaulMcKenzie

ответ

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

Вы только читаете первые 11 символов в строке! Увеличьте MAX_LINE_NUMBERи переименуйте его на что-то вроде MAX_LINE_LENGTH, и он должен работать.

Пояснение: when reading using fgets,

fgets() считывает максимум на один меньше, чем размера символов из потока

ваши примеры:

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

OMG! Спасибо, я пытаюсь понять это с помощью отладчика для 3 часа! СПАСИБО – limitless

+1

:) Рад помочь! – cxw

+0

@limitless, что вы на самом деле отлаживали? Глядя на переменную 'line' на секунду, должно быть достаточно, чтобы понять, что проблема долгое время происходила до первого' strtok'. – grek40

Смежные вопросы