2016-08-19 9 views
1

アイムこの形式の行を解析してみてください:2つの区切り文字,(スペースやカンマ)でstrtok()機能を使用してはstrtok()の戻りNULL

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

そうイム しかし何らかの理由で私が6になると関数は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を取得します。私は'fil'取得していますし、次の反復がNULLなりますfileNameためfile2を取得sould

file1: file2,file3,file4 

:この入力で

。それはあなたが唯一の行の最初の11個の文字を読んでいる

#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; '注意:strlen()はゼロを返すことができます。 (ファイル名はこの場合はNULLでもかまいません) – joop

+0

ありがとうございますが、私はそこに空の行はないはずです。 – limitless

+0

"ok"と仮定するのではなく、ハードコードされたデータを持つ小さなメインプログラムを書くのはなぜですか? – PaulMcKenzie

答えて

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

を助けていた場合

これは完全なコードです! MAX_LINE_NUMBERを増やしての名前をMAX_LINE_LENGTHに変更してください。

説明:when reading using fgets

のfgets()で最も1 サイズのストリーム

から文字

あなたの例未満で読み取ります

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

関連する問題