limitless
limitless

Reputation: 669

strtok() return NULL in the middle of the parsing

I'm try to parse a line in this format :

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

so Im using the strtok() function with 2 delimiters and , (space and comma) But for some reason when i get to 6 the funcion return 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);
}

So when the fileName should be 6, i get NULL.

With this input :

file1: file2,file3,file4

Where i sould get file2 for the fileName I'm getting 'fil' , and the next iteration will be NULL.

This is the full code if it's help

#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;
}

Upvotes: 1

Views: 468

Answers (1)

cxw
cxw

Reputation: 17051

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

You are only reading the first 11 characters of the line! Increase MAX_LINE_NUMBER and rename it to something like MAX_LINE_LENGTH and it should work.

Explanation: when reading using fgets,

fgets() reads in at most one less than size characters from stream

Your examples:

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

Upvotes: 2

Related Questions