1

さて、最終プロジェクトのこのプログラムはほぼ完成しましたが、セグメンテーション違反が発生しています...プログラムはすべてを正しく実行し、すべてを画面に出力しますが、機能からは抜けませんprintWordLength()。最後にセグメンテーション違反が表示されます。これは簡単な修正であると確信していますが、現時点では私の脳はクラッシュしています。(犯人の印刷機能については、一番下までスクロールします。

私のコードを使いたいだけなら、お気軽に。

目的:このプログラムは、コマンド ライン引数として入力されたファイルを読み取り、ファイルから各行を読み取り、行から各単語をトークン化し、各単語について、その長さに応じて Word Length 構造体に配置する双方向リンク リストを保持します。次に、単語の文字列に依存する word_count 構造体に配置し、ファイル内の各単語の出現をカウントします。

#include <stdio.h>
#include <string.h>
#include <stdlib.h>

#define DELIM " ,.+-=!?:;\t"
#define MAXLINE 25000

typedef struct word_count
{
    char * word;
    int count;
    struct word_count *next;
    struct word_count *prev;
} WORD;

typedef struct word_length_count
{
    int length;
    int count;
    WORD * words;
    struct word_length_count *next;
    struct word_length_count *prev;
} WLENGTH;

int splitIntoWords(char line[]);
void processLength(char * word);
void processWord(char * word, WORD * wordCount);
void printWordLength();
WLENGTH * createWordLength(char *word);
WORD * createWordCount(char *word);

WLENGTH * wordLength = NULL;

int main(unsigned int argc, unsigned char *argv[]){
    FILE *fpin;
    char line[MAXLINE];
    int totalWordCount = 0;

    if((fpin = fopen(argv[1], "r")) == NULL)
    {
            printf("Can't open input file.\n");
            exit(-1);
    }

    printf("This is the words all tokenized from the input!\n");
    while(fgets(line, MAXLINE, fpin) != NULL)
    {
            line[strcspn(line, "\n")] = '\0';
            if(line[0] == '\0')
                    continue;
            totalWordCount += splitIntoWords(line);
    }
    printf("Total number of words is: %d\n", totalWordCount);
    printWordLength();
    printf("\nFINISHED!");
}

int splitIntoWords(char line[])
{
    char *word;
    int count=0;
    word = strtok(line, DELIM);
    for(;word != NULL;)
    {
            count++;
            printf("%s\n", word);
            processLength(word);
            word = strtok(NULL, DELIM);
    }
    return count;
}

void processLength(char * word)
{
    WLENGTH *wLCounter = NULL;
    WLENGTH *wLLast = NULL;

    if(wordLength == NULL)
    {
            wordLength = createWordLength(word);
            return;
    }

    wLCounter = wordLength;

    while(wLCounter != NULL)
    {
            if(strlen(word) == wLCounter->length)
            {
                    ++wLCounter->count;
                    processWord(word, wLCounter->words);
                    return;
            }
            wLLast = wLCounter;
            wLCounter = wLCounter->next;
    }
    wLLast->next = createWordLength(word);
}

void processWord(char * word, WORD * wordCount){
    WORD * wCounter = NULL;
    WORD * wLast = NULL;

    if(wordCount == NULL)
    {
            wordCount = createWordCount(word);
            return;
    }
    wCounter = wordCount;
    while(wCounter != NULL)
    {
            if(strcmp(word, wCounter->word) == 0)
            {
                    ++wCounter->count;
                    return;
            }
            wLast = wCounter;
            wCounter = wCounter->next;
    }
    wLast->next = createWordCount(word);
}

WLENGTH * createWordLength(char *word)
{
    WLENGTH *wLCounter = NULL;
    wLCounter = (WLENGTH*)malloc(sizeof(WLENGTH));
    //wLCounter->count = (int*)malloc(int));
    //wLCounter->length = (int*)malloc(int));
    wLCounter->words = createWordCount(word);
    wLCounter->count = 1;
    wLCounter->length = strlen(word);
    wLCounter->next = NULL;
    return wLCounter;
}

WORD * createWordCount(char *word)
{
    WORD *wCount = NULL;
    wCount = (WORD*)malloc(sizeof(WORD));
    wCount->word = (char*)malloc(strlen(word+1));
    strcpy(wCount->word, word);
    wCount->count = 1;
    wCount->next = NULL;
    return wCount;
}

void printWordLength(){
    WLENGTH * temp = wordLength;
    WORD * tempWORD = wordLength->words;
    while(temp != NULL)
    {
            tempWORD = temp->words;
            printf("\nFor Word Length: %d : There are: %d occurances!\n",  temp->length, temp->count);
            while(tempWORD != NULL)
            {
                    printf("\t%s\toccurs:%d\n", tempWORD->word, tempWORD->count);
                    tempWORD = tempWORD->next;
            }
            temp = temp->next;
    }
}

while ループ for を追加するまで、セグメンテーション違反は発生しませんでしたtempWORD。しかし、私が持っている脳のおならの瞬間は、私が問題を知らないということです. たぶんポインタの問題?

4

1 に答える 1

1

コードを理解する努力をしないと、最後の行が問題のように見えます - tempWORD = temp->words を割り当てる前に temp != NULL をチェックする必要があります。temp->next に移動する前に tempWord = temp->words の割り当てを行うつもりでない限り

于 2012-05-03T02:39:02.917 に答える