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
我应该得到 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;
}
#define MAX_LINE_NUMBER 11
...
char line[MAX_LINE_NUMBER];
...
while (fgets(line, sizeof(line), fPointer))
您只阅读了该行的前 11 个字符!增加 MAX_LINE_NUMBER
并将其 重命名为 MAX_LINE_LENGTH
之类的名称,它应该可以工作。
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
我正在尝试以这种格式解析一行:
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
我应该得到 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;
}
#define MAX_LINE_NUMBER 11
...
char line[MAX_LINE_NUMBER];
...
while (fgets(line, sizeof(line), fPointer))
您只阅读了该行的前 11 个字符!增加 MAX_LINE_NUMBER
并将其 重命名为 MAX_LINE_LENGTH
之类的名称,它应该可以工作。
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