strtok() return 解析中间为NULL

strtok() return NULL in the middle of the parsing

我正在尝试以这种格式解析一行:

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

所以我使用带有 2 个分隔符 </code> 和 <code>,(space 和逗号)的 strtok() 函数 但是由于某种原因,当我到达 6 时,函数 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);
}

所以当文件名应该是 6 时,我得到 NULL

有了这个输入:

file1: file2,file3,file4

我应该得到 file2fileName 我得到 '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;
}
#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() reads in at most one less than size characters from stream

你的例子:

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