この関数のタスクはかなり簡単です。char* の配列、ファイルへのポインター、および最大ワード サイズを指定すると、ファイルを読み取り、各ワードを 1 つずつ char* 配列にコピーします。\n
ファイルには 1 行に 1 つの単語があるため、単語間の区切りとして使用するのが理にかなっています。そのことを念頭に置いて、コードは非常に簡単に解釈できるはずです。
void loadDictionary(char* strDictionary[], FILE* filePointer, int nMaxLetters)
{
int nNameCount= 0, nCursor = 0;
char* strCurrent;
char cCurrent;
//allocate space for a word
strCurrent = malloc(nMaxLetters * sizeof(char));
while ((cCurrent = fgetc(filePointer)) != EOF) {
if(cCurrent != '\n')
{
strCurrent[nCursor] = cCurrent;
nCursor++;
} else { //then we've reached the end of the line (word)
//add null termination to string
strCurrent[nCursor] = '\0'; //SEG FAULT
//copy string to dictionary
memcpy(strDictionary[nNameCount], strCurrent, strlen(strCurrent)+1);
//increment count
nNameCount++;
//reset the cursor
nCursor = 0;
}
}
}
このコードは、 を呼び出す行でセグメンテーション違反を生成しますstrCurrent[nCursor] = '\0';
。一見すると、この操作は、私が呼び出す他のブロックの操作と変わらないように見えるため、理由はわかりませんstrCurrent[nCursor] = cCurrent;
。strCurrent は、必要なすべての文字を格納するのに十分なスペースを割り当てているはずです。だから、私はやや途方に暮れています。これを理解するのを手伝ってください、みんな。
注:このタスクを実行するfgets
代わりに、使用する方がおそらく簡単だと思います。fgetc
私はそれに切り替えるかもしれません。しかし、理解できないエラーに遭遇したので、理解するまで放置したくありません。
編集:
おそらく不適切に割り当てられているmemcpy
ために、操作でエラーが発生する可能性があると誰かが指摘しました。が割り当てられるブロックは次strDictionary
のとおりです。おそらく私は間違いを犯しました:main
strDictionary
int main(int argc, char* argv[])
{
char** strDictionary;
FILE* filePointer;
int nResults = 0, nLines = 0, nNumLines, nMaxChars, i;
filePointer = fopen("dictionary.txt", "r");
//obtain the number of lines and the maximum word size of the dictionary
countLines(filePointer, &nNumLines, &nMaxChars);
//allocate memory for strDictionary
strDictionary = malloc(nNumLines * nMaxChars * sizeof(char));
printf("%d words in dictionary. Longest word is %d letters\n",
nNumLines, nMaxChars);
//Output here correctly prints: 1000 and 21
//reset the file pointer (not sure if this is a necessary step, but oh well)
filePointer = fopen("dictionary.txt", "r");
//load dictionary into memory
loadDictionary(strDictionary, filePointer, nMaxChars);
for (i=0; i<10; i++)
printf("%dth element of dictionary: %s\n", i, strDictionary[i]);
return 0;
}
編集2:
OK、関数を大幅に簡素化するfgets()
代わりに使用することにしました。の正しい操作fgetc()
だと思ったことも実行しました。ただし、まだセグフォルトが発生しています。更新されたコードは次のとおりです。malloc()
strDictionary
void loadDictionary(char* strDictionary[], FILE* filePointer, int nMaxLetters)
{
printf("Call to loadDictionary. nMaxLetters = %d\n", nMaxLetters);
int nWordCount= 0, nCursor = 0;
char* strCurrent;
char cCurrent;
strCurrent = malloc(nMaxLetters); //allocate space for a word
while (fgets(strCurrent, nMaxLetters, filePointer) != NULL)
{
memcpy(strDictionary[nWordCount], strCurrent, strlen(strCurrent)+1);
nWordCount++;
}
}
int main(int argc, char* argv[])
{
char** strDictionary;
FILE* filePointer;
int nResults = 0, nLines = 0, nNumLines, nMaxChars, i;
filePointer = fopen("dictionary.txt", "r");
//count the lines in the file (works fine)
countLines(filePointer, &nNumLines, &nMaxChars);
//allocate space for the dictionary
strDictionary = malloc(nNumLines * sizeof(char*));
for (i = 0; i<nLines; i++)
strDictionary[i] = malloc(nMaxChars * sizeof(char));
printf("%d words in dictionary. Longest word is %d letters\n",
nNumLines, nMaxChars);
//load dictionary into array
filePointer = fopen("dictionary.txt", "r");
loadDictionary(strDictionary, filePointer, nMaxChars);
for (i=0; i<10; i++)
printf("%dth element of dictionary: %s\n", i, strDictionary[i]);
return 0;
}