C 指向三个不同链表的指针有问题

C 指向三个不同链表的指针有问题,c,pointers,linked-list,C,Pointers,Linked List,我对C程序中的指针有问题,这些指针计算一组文件中一个或多个字符串的出现次数。程序将输入一个文件,其中包含搜索事件的文件路径。我将提到的所有文件都包含在项目的同一文件夹中,其名称为“find”。在我的例子中,输入文件是“path.txt”: try.txt的内容是: abc abc abc ac ac ac ac ac ac ac ac abc abc abc try1.txt的内容是: abc abc abc ac ac ac ac ac ac ac ac abc abc abc 我的程

我对C程序中的指针有问题,这些指针计算一组文件中一个或多个字符串的出现次数。程序将输入一个文件,其中包含搜索事件的文件路径。我将提到的所有文件都包含在项目的同一文件夹中,其名称为“find”。在我的例子中,输入文件是“path.txt”:

try.txt的内容是:

abc
abc
abc
ac
ac
ac
ac
ac
ac
ac
ac
abc
abc
abc
try1.txt的内容是:

abc
abc
abc
ac
ac
ac
ac
ac
ac
ac
ac
abc
abc
abc
我的程序由4个文件、两个头文件和两个源文件组成:

find.c:

#include "find.h"

int main(int argc, char * argv[]){

FILE *fInput = NULL;  
FILE *fp = NULL;
char *line1; 
char *line2;
int endOfLineDetected = 0;
size_t nrOfCharRead = 0;
char ch;

fWord *w = NULL;
fWord *start = NULL;
fWord *tail = NULL;

fPath *head = NULL;
fPath *current = NULL;


fInput = fopen(argv[1], "r"); //the file that contains the path of the file in which search.

if(fInput == NULL){
    fprintf(stderr, "Cannot open %s, exiting. . .\n", argv[1]);
    exit(1);
}

while(!endOfLineDetected){ //read line by line the input file in order to save the path in a structure
    line1 = getLineOfAnySize(fInput,128,&endOfLineDetected,&nrOfCharRead);
    fPath *node = malloc (sizeof(fPath));
    node->path = line1;
    node->fileOccurrences = 0;
    node->position = NULL;
    node->next = NULL;

    if(head == NULL){
        current = head = node;
    }else{
        current = current->next = node;
    }
}

fclose(fInput);

//create a linked list of the type fWord, one structure for each word.
do{
    fWord *app = malloc(sizeof(fWord));
    printf("Insert the word to search: ");
    scanf("%s", app->word);
    app->totalOccurences = 0;
    app->p = head;
    app->next = NULL;

    if(start == NULL){
        tail = start = app;
    }else{
        tail = tail->next = app;
    }
    printf("Do you want to insert another word? (Y/N): ");
    scanf(" %c", &ch);
}while(ch == 'y' || ch == 'Y');

w = start; //pointer back to the top of the fWord structure

//traverse all the structure and execute the algorithm
while(w != NULL){
    while(w->p != NULL){
        fp = fopen(w->p->path, "r");
        if(fp == NULL){
            fprintf(stderr, "Cannot open %s, exiting. . .\n", w->p->path);
            exit(1);
        }

        int countLine = 0;
        w->p->fileOccurrences = 0;
        endOfLineDetected = 0;

        while(!endOfLineDetected){
            line2 = getLineOfAnySize(fp,128,&endOfLineDetected,&nrOfCharRead);
            int n = strlen(line2);
            int m = strlen(w->word);
            w->p->fileOccurrences = w->p->fileOccurrences + KMP(line2, w->word, n, m, countLine, w->p);
            countLine = countLine + 1;
        }   

        w->totalOccurences = w->totalOccurences + w->p->fileOccurrences;
        w->p->position = getHead(); // //pointer back to the top of the  fPosition structure
        w->p = w->p->next;
        fclose(fp);
    }
    w->p = head; //pointer back to the top of the fPath structure
}

w = start; //pointer back to the top of the fWord structure

//traverse all the structure and print out the occurrences and their position
while(w != NULL){
    w->p = head;
    printf("WORD %s \r\n", w->word);
    printf("TOTAL %d \r\n", w->totalOccurences);
    while(w->p != NULL){
        printf("FILE %s \r\n", w->p->path);
        printf("OCCURENCES %d   \r\n", w->p->fileOccurrences);
        while (w->p->position != NULL){
            printf("%d %d\r\n", w->p->position->line, w->p->position->character);
            w->p->position = w->p->position->next;
        }
        w->p = w->p->next;
    }
    w = w->next;
}

printf("\r\n"); //the file ends with an empty line

return 0;
}

//method used for read line by line a file
char * getLineOfAnySize(FILE* fp, size_t typicalSize, int *endOfLineDetected,size_t *nrOfCharRead){ 
char *line;       // buffer for our string
int ch;           // we will read line character by character
size_t len = 0;   // number of characters read (character counter)
size_t lineSize = typicalSize;  // initial size of the buffer allocated for the line
*nrOfCharRead = 0;

if(!fp) return NULL; // protection

// allocating the buffer
line = realloc(NULL, sizeof(char)*lineSize); // expected size of the line is up to typicalSize

if (!line) return line; // protection, if we fail to allocate the memory we will return NULL

while (1) { // loop forever     
    ch = fgetc(fp);       // getting character by character from file

    if (ch == '\n') break; // end of line detected - breaking the loop 
    if( ch == EOF)  {
        *endOfLineDetected = 1;
        break; // end of file detected - breaking the loop
     }

    line[len++] = ch;     // store the character in the line buffer, increase character counter

    if (len == lineSize){ // we reached the end of line buffer (no more room)

        lineSize = lineSize + 64; // we have to increase the line size 
        line = realloc(line, sizeof(char)*(lineSize)); // line buffer has new size now

        if (!line) return line; // if we fail to allocate memory we will return NULL
    }
    if( (len == 0) && *endOfLineDetected){ // empty file
        *endOfLineDetected = 1;
        break; 
    } 
}


line[len++] ='\0';  // ending the string (notice there is no '\n' in the string)
*nrOfCharRead = len;

return line;       // return the string
}
#include "kmp.h"

char * getLineOfAnySize(FILE* fp, size_t typicalSize, int *endOfLineDetected,size_t *nrOfCharRead);
#include "kmp.h"

fPosition *head = NULL;
fPosition *current = NULL;

// Function to implement KMP algorithm
int KMP(const char* X, const char* Y, int m, int n, int line, fPath *app){

int count = 0;

// next[i] stores the index of next best partial match
int next[n + 1];

for (int i = 0; i < n + 1; i++)
    next[i] = 0;

for (int i = 1; i < n; i++){
    int j = next[i + 1];

    while (j > 0 && Y[j] != Y[i])
        j = next[j];

    if (j > 0 || Y[j] == Y[i])
        next[i + 1] = j + 1;
}

for (int i = 0, j = 0; i < m; i++){
    if (*(X + i) == *(Y + j)){
        if (++j == n){
            count = count + 1; //count the occurrences of the string in this file   
            fPosition *node = malloc (sizeof(fPosition));
            node->line = line; //the current line
            node->character = i - j + 1; //the shift in which occurs
            node->next = NULL;

            if(head == NULL){
                current = head = node;
            }else{
                current = current->next = node;
            }

            app->position = current;

        }
    }
    else if (j > 0) {
        j = next[j];
        i--;    // since i will be incremented in next iteration
    }
}

    return count; //return the number of occurences found
}

//take the pointer back to the top of fPosition
fPosition * getHead(){ 
     fPosition *app = head;
     head = NULL;
     return app;
}
#include<stdio.h>
#include<stdlib.h>
#include<string.h>

struct filePath{
char *path; //the file path
struct filePath *next;
};

struct OccurrencesPosition{
int line; //line in which an occurrence is founded
int character; //shift at which the occurrences comes

struct filePath pathInfo;

struct OccurrencesPosition *next; //pointer to the next occurrences
};

struct fileWord{
char word[50]; //the string to search
int totalOccurences; //the total occurrences of the string

int fileOccurrences; //the occurrences of each file
struct OccurrencesPosition *position; //pointer to the linked list which tracks all the occurrences and their positions

struct fileWord *next; //pointer to the next word
};

typedef struct filePath fPath; 
typedef struct fileWord fWord;
typedef struct OccurrencesPosition fPosition;

fPosition * getHead();


int KMP(const char* X, const char* Y, int m, int n, int line, fPath *app);
find.h:

#include "find.h"

int main(int argc, char * argv[]){

FILE *fInput = NULL;  
FILE *fp = NULL;
char *line1; 
char *line2;
int endOfLineDetected = 0;
size_t nrOfCharRead = 0;
char ch;

fWord *w = NULL;
fWord *start = NULL;
fWord *tail = NULL;

fPath *head = NULL;
fPath *current = NULL;


fInput = fopen(argv[1], "r"); //the file that contains the path of the file in which search.

if(fInput == NULL){
    fprintf(stderr, "Cannot open %s, exiting. . .\n", argv[1]);
    exit(1);
}

while(!endOfLineDetected){ //read line by line the input file in order to save the path in a structure
    line1 = getLineOfAnySize(fInput,128,&endOfLineDetected,&nrOfCharRead);
    fPath *node = malloc (sizeof(fPath));
    node->path = line1;
    node->fileOccurrences = 0;
    node->position = NULL;
    node->next = NULL;

    if(head == NULL){
        current = head = node;
    }else{
        current = current->next = node;
    }
}

fclose(fInput);

//create a linked list of the type fWord, one structure for each word.
do{
    fWord *app = malloc(sizeof(fWord));
    printf("Insert the word to search: ");
    scanf("%s", app->word);
    app->totalOccurences = 0;
    app->p = head;
    app->next = NULL;

    if(start == NULL){
        tail = start = app;
    }else{
        tail = tail->next = app;
    }
    printf("Do you want to insert another word? (Y/N): ");
    scanf(" %c", &ch);
}while(ch == 'y' || ch == 'Y');

w = start; //pointer back to the top of the fWord structure

//traverse all the structure and execute the algorithm
while(w != NULL){
    while(w->p != NULL){
        fp = fopen(w->p->path, "r");
        if(fp == NULL){
            fprintf(stderr, "Cannot open %s, exiting. . .\n", w->p->path);
            exit(1);
        }

        int countLine = 0;
        w->p->fileOccurrences = 0;
        endOfLineDetected = 0;

        while(!endOfLineDetected){
            line2 = getLineOfAnySize(fp,128,&endOfLineDetected,&nrOfCharRead);
            int n = strlen(line2);
            int m = strlen(w->word);
            w->p->fileOccurrences = w->p->fileOccurrences + KMP(line2, w->word, n, m, countLine, w->p);
            countLine = countLine + 1;
        }   

        w->totalOccurences = w->totalOccurences + w->p->fileOccurrences;
        w->p->position = getHead(); // //pointer back to the top of the  fPosition structure
        w->p = w->p->next;
        fclose(fp);
    }
    w->p = head; //pointer back to the top of the fPath structure
}

w = start; //pointer back to the top of the fWord structure

//traverse all the structure and print out the occurrences and their position
while(w != NULL){
    w->p = head;
    printf("WORD %s \r\n", w->word);
    printf("TOTAL %d \r\n", w->totalOccurences);
    while(w->p != NULL){
        printf("FILE %s \r\n", w->p->path);
        printf("OCCURENCES %d   \r\n", w->p->fileOccurrences);
        while (w->p->position != NULL){
            printf("%d %d\r\n", w->p->position->line, w->p->position->character);
            w->p->position = w->p->position->next;
        }
        w->p = w->p->next;
    }
    w = w->next;
}

printf("\r\n"); //the file ends with an empty line

return 0;
}

//method used for read line by line a file
char * getLineOfAnySize(FILE* fp, size_t typicalSize, int *endOfLineDetected,size_t *nrOfCharRead){ 
char *line;       // buffer for our string
int ch;           // we will read line character by character
size_t len = 0;   // number of characters read (character counter)
size_t lineSize = typicalSize;  // initial size of the buffer allocated for the line
*nrOfCharRead = 0;

if(!fp) return NULL; // protection

// allocating the buffer
line = realloc(NULL, sizeof(char)*lineSize); // expected size of the line is up to typicalSize

if (!line) return line; // protection, if we fail to allocate the memory we will return NULL

while (1) { // loop forever     
    ch = fgetc(fp);       // getting character by character from file

    if (ch == '\n') break; // end of line detected - breaking the loop 
    if( ch == EOF)  {
        *endOfLineDetected = 1;
        break; // end of file detected - breaking the loop
     }

    line[len++] = ch;     // store the character in the line buffer, increase character counter

    if (len == lineSize){ // we reached the end of line buffer (no more room)

        lineSize = lineSize + 64; // we have to increase the line size 
        line = realloc(line, sizeof(char)*(lineSize)); // line buffer has new size now

        if (!line) return line; // if we fail to allocate memory we will return NULL
    }
    if( (len == 0) && *endOfLineDetected){ // empty file
        *endOfLineDetected = 1;
        break; 
    } 
}


line[len++] ='\0';  // ending the string (notice there is no '\n' in the string)
*nrOfCharRead = len;

return line;       // return the string
}
#include "kmp.h"

char * getLineOfAnySize(FILE* fp, size_t typicalSize, int *endOfLineDetected,size_t *nrOfCharRead);
#include "kmp.h"

fPosition *head = NULL;
fPosition *current = NULL;

// Function to implement KMP algorithm
int KMP(const char* X, const char* Y, int m, int n, int line, fPath *app){

int count = 0;

// next[i] stores the index of next best partial match
int next[n + 1];

for (int i = 0; i < n + 1; i++)
    next[i] = 0;

for (int i = 1; i < n; i++){
    int j = next[i + 1];

    while (j > 0 && Y[j] != Y[i])
        j = next[j];

    if (j > 0 || Y[j] == Y[i])
        next[i + 1] = j + 1;
}

for (int i = 0, j = 0; i < m; i++){
    if (*(X + i) == *(Y + j)){
        if (++j == n){
            count = count + 1; //count the occurrences of the string in this file   
            fPosition *node = malloc (sizeof(fPosition));
            node->line = line; //the current line
            node->character = i - j + 1; //the shift in which occurs
            node->next = NULL;

            if(head == NULL){
                current = head = node;
            }else{
                current = current->next = node;
            }

            app->position = current;

        }
    }
    else if (j > 0) {
        j = next[j];
        i--;    // since i will be incremented in next iteration
    }
}

    return count; //return the number of occurences found
}

//take the pointer back to the top of fPosition
fPosition * getHead(){ 
     fPosition *app = head;
     head = NULL;
     return app;
}
#include<stdio.h>
#include<stdlib.h>
#include<string.h>

struct filePath{
char *path; //the file path
struct filePath *next;
};

struct OccurrencesPosition{
int line; //line in which an occurrence is founded
int character; //shift at which the occurrences comes

struct filePath pathInfo;

struct OccurrencesPosition *next; //pointer to the next occurrences
};

struct fileWord{
char word[50]; //the string to search
int totalOccurences; //the total occurrences of the string

int fileOccurrences; //the occurrences of each file
struct OccurrencesPosition *position; //pointer to the linked list which tracks all the occurrences and their positions

struct fileWord *next; //pointer to the next word
};

typedef struct filePath fPath; 
typedef struct fileWord fWord;
typedef struct OccurrencesPosition fPosition;

fPosition * getHead();


int KMP(const char* X, const char* Y, int m, int n, int line, fPath *app);
kmp.c:

#include "find.h"

int main(int argc, char * argv[]){

FILE *fInput = NULL;  
FILE *fp = NULL;
char *line1; 
char *line2;
int endOfLineDetected = 0;
size_t nrOfCharRead = 0;
char ch;

fWord *w = NULL;
fWord *start = NULL;
fWord *tail = NULL;

fPath *head = NULL;
fPath *current = NULL;


fInput = fopen(argv[1], "r"); //the file that contains the path of the file in which search.

if(fInput == NULL){
    fprintf(stderr, "Cannot open %s, exiting. . .\n", argv[1]);
    exit(1);
}

while(!endOfLineDetected){ //read line by line the input file in order to save the path in a structure
    line1 = getLineOfAnySize(fInput,128,&endOfLineDetected,&nrOfCharRead);
    fPath *node = malloc (sizeof(fPath));
    node->path = line1;
    node->fileOccurrences = 0;
    node->position = NULL;
    node->next = NULL;

    if(head == NULL){
        current = head = node;
    }else{
        current = current->next = node;
    }
}

fclose(fInput);

//create a linked list of the type fWord, one structure for each word.
do{
    fWord *app = malloc(sizeof(fWord));
    printf("Insert the word to search: ");
    scanf("%s", app->word);
    app->totalOccurences = 0;
    app->p = head;
    app->next = NULL;

    if(start == NULL){
        tail = start = app;
    }else{
        tail = tail->next = app;
    }
    printf("Do you want to insert another word? (Y/N): ");
    scanf(" %c", &ch);
}while(ch == 'y' || ch == 'Y');

w = start; //pointer back to the top of the fWord structure

//traverse all the structure and execute the algorithm
while(w != NULL){
    while(w->p != NULL){
        fp = fopen(w->p->path, "r");
        if(fp == NULL){
            fprintf(stderr, "Cannot open %s, exiting. . .\n", w->p->path);
            exit(1);
        }

        int countLine = 0;
        w->p->fileOccurrences = 0;
        endOfLineDetected = 0;

        while(!endOfLineDetected){
            line2 = getLineOfAnySize(fp,128,&endOfLineDetected,&nrOfCharRead);
            int n = strlen(line2);
            int m = strlen(w->word);
            w->p->fileOccurrences = w->p->fileOccurrences + KMP(line2, w->word, n, m, countLine, w->p);
            countLine = countLine + 1;
        }   

        w->totalOccurences = w->totalOccurences + w->p->fileOccurrences;
        w->p->position = getHead(); // //pointer back to the top of the  fPosition structure
        w->p = w->p->next;
        fclose(fp);
    }
    w->p = head; //pointer back to the top of the fPath structure
}

w = start; //pointer back to the top of the fWord structure

//traverse all the structure and print out the occurrences and their position
while(w != NULL){
    w->p = head;
    printf("WORD %s \r\n", w->word);
    printf("TOTAL %d \r\n", w->totalOccurences);
    while(w->p != NULL){
        printf("FILE %s \r\n", w->p->path);
        printf("OCCURENCES %d   \r\n", w->p->fileOccurrences);
        while (w->p->position != NULL){
            printf("%d %d\r\n", w->p->position->line, w->p->position->character);
            w->p->position = w->p->position->next;
        }
        w->p = w->p->next;
    }
    w = w->next;
}

printf("\r\n"); //the file ends with an empty line

return 0;
}

//method used for read line by line a file
char * getLineOfAnySize(FILE* fp, size_t typicalSize, int *endOfLineDetected,size_t *nrOfCharRead){ 
char *line;       // buffer for our string
int ch;           // we will read line character by character
size_t len = 0;   // number of characters read (character counter)
size_t lineSize = typicalSize;  // initial size of the buffer allocated for the line
*nrOfCharRead = 0;

if(!fp) return NULL; // protection

// allocating the buffer
line = realloc(NULL, sizeof(char)*lineSize); // expected size of the line is up to typicalSize

if (!line) return line; // protection, if we fail to allocate the memory we will return NULL

while (1) { // loop forever     
    ch = fgetc(fp);       // getting character by character from file

    if (ch == '\n') break; // end of line detected - breaking the loop 
    if( ch == EOF)  {
        *endOfLineDetected = 1;
        break; // end of file detected - breaking the loop
     }

    line[len++] = ch;     // store the character in the line buffer, increase character counter

    if (len == lineSize){ // we reached the end of line buffer (no more room)

        lineSize = lineSize + 64; // we have to increase the line size 
        line = realloc(line, sizeof(char)*(lineSize)); // line buffer has new size now

        if (!line) return line; // if we fail to allocate memory we will return NULL
    }
    if( (len == 0) && *endOfLineDetected){ // empty file
        *endOfLineDetected = 1;
        break; 
    } 
}


line[len++] ='\0';  // ending the string (notice there is no '\n' in the string)
*nrOfCharRead = len;

return line;       // return the string
}
#include "kmp.h"

char * getLineOfAnySize(FILE* fp, size_t typicalSize, int *endOfLineDetected,size_t *nrOfCharRead);
#include "kmp.h"

fPosition *head = NULL;
fPosition *current = NULL;

// Function to implement KMP algorithm
int KMP(const char* X, const char* Y, int m, int n, int line, fPath *app){

int count = 0;

// next[i] stores the index of next best partial match
int next[n + 1];

for (int i = 0; i < n + 1; i++)
    next[i] = 0;

for (int i = 1; i < n; i++){
    int j = next[i + 1];

    while (j > 0 && Y[j] != Y[i])
        j = next[j];

    if (j > 0 || Y[j] == Y[i])
        next[i + 1] = j + 1;
}

for (int i = 0, j = 0; i < m; i++){
    if (*(X + i) == *(Y + j)){
        if (++j == n){
            count = count + 1; //count the occurrences of the string in this file   
            fPosition *node = malloc (sizeof(fPosition));
            node->line = line; //the current line
            node->character = i - j + 1; //the shift in which occurs
            node->next = NULL;

            if(head == NULL){
                current = head = node;
            }else{
                current = current->next = node;
            }

            app->position = current;

        }
    }
    else if (j > 0) {
        j = next[j];
        i--;    // since i will be incremented in next iteration
    }
}

    return count; //return the number of occurences found
}

//take the pointer back to the top of fPosition
fPosition * getHead(){ 
     fPosition *app = head;
     head = NULL;
     return app;
}
#include<stdio.h>
#include<stdlib.h>
#include<string.h>

struct filePath{
char *path; //the file path
struct filePath *next;
};

struct OccurrencesPosition{
int line; //line in which an occurrence is founded
int character; //shift at which the occurrences comes

struct filePath pathInfo;

struct OccurrencesPosition *next; //pointer to the next occurrences
};

struct fileWord{
char word[50]; //the string to search
int totalOccurences; //the total occurrences of the string

int fileOccurrences; //the occurrences of each file
struct OccurrencesPosition *position; //pointer to the linked list which tracks all the occurrences and their positions

struct fileWord *next; //pointer to the next word
};

typedef struct filePath fPath; 
typedef struct fileWord fWord;
typedef struct OccurrencesPosition fPosition;

fPosition * getHead();


int KMP(const char* X, const char* Y, int m, int n, int line, fPath *app);
如您所见,WORD和TOTAL在这两种情况下都是正确的,但出现的次数却不正确。在这两种情况下,它们都对应于“ac”。 正确的输出应为:

WORD abc 
TOTAL 6 
FILE C:\Users\Utente\Desktop\find\try.txt 
OCCURENCES 3    
0 0
0 1
0 2
FILE C:\Users\Utente\Desktop\find\try1.txt 
OCCURENCES 3   
4 0
5 0
6 0
WORD ac 
TOTAL 8 
FILE C:\Users\Utente\Desktop\find\try.txt 
OCCURENCES 4
3 0
4 0
5 0
6 0    
FILE C:\Users\Utente\Desktop\find\try1.txt 
OCCURENCES 4
0 0
1 0
2 0
3 0
我认为问题在于fPosition指针。感谢所有帮助您的人。

您遇到了设计问题

问题是您作为
filePath
列表的一部分维护的事件信息

struct filePath{
    char *path; //the file path
    int fileOccurrences; //the occurrences of each file
    struct OccurrencesPosition *position;  // here *****************
    struct filePath *next;
};
struct fileWord{
    char word[50]; //the string to search
    int totalOccurences; //the total occurrences of the string
    struct filePath *p; //pointer to the linked list of all the files
    struct fileWord *next; //pointer to the next word
};
以及作为
fileWord
列表的一部分维护的文件路径信息

struct filePath{
    char *path; //the file path
    int fileOccurrences; //the occurrences of each file
    struct OccurrencesPosition *position;  // here *****************
    struct filePath *next;
};
struct fileWord{
    char word[50]; //the string to search
    int totalOccurences; //the total occurrences of the string
    struct filePath *p; //pointer to the linked list of all the files
    struct fileWord *next; //pointer to the next word
};
由于您只有一个文件路径列表,所以
fileWord
列表中的每个单词实际上都指向相同的
filepath
列表

struct filePath{
    char *path; //the file path
    int fileOccurrences; //the occurrences of each file
    struct OccurrencesPosition *position;  // here *****************
    struct filePath *next;
};
struct fileWord{
    char word[50]; //the string to search
    int totalOccurences; //the total occurrences of the string
    struct filePath *p; //pointer to the linked list of all the files
    struct fileWord *next; //pointer to the next word
};

每个单词都指向相同的文件路径列表

fWord *app = malloc(sizeof(fWord));
printf("Insert the word to search: ");
scanf("%s", app->word);

app->p = head; //here
您正在更新
文件路径中每个单词的位置信息

      w->p->position = getHead(); // //pointer back to the top of the  fPosition structure
因此,
filePath
list仅保存您搜索的最新单词的位置信息


更新:

#include "find.h"

int main(int argc, char * argv[]){

FILE *fInput = NULL;  
FILE *fp = NULL;
char *line1; 
char *line2;
int endOfLineDetected = 0;
size_t nrOfCharRead = 0;
char ch;

fWord *w = NULL;
fWord *start = NULL;
fWord *tail = NULL;

fPath *head = NULL;
fPath *current = NULL;


fInput = fopen(argv[1], "r"); //the file that contains the path of the file in which search.

if(fInput == NULL){
    fprintf(stderr, "Cannot open %s, exiting. . .\n", argv[1]);
    exit(1);
}

while(!endOfLineDetected){ //read line by line the input file in order to save the path in a structure
    line1 = getLineOfAnySize(fInput,128,&endOfLineDetected,&nrOfCharRead);
    fPath *node = malloc (sizeof(fPath));
    node->path = line1;
    node->fileOccurrences = 0;
    node->position = NULL;
    node->next = NULL;

    if(head == NULL){
        current = head = node;
    }else{
        current = current->next = node;
    }
}

fclose(fInput);

//create a linked list of the type fWord, one structure for each word.
do{
    fWord *app = malloc(sizeof(fWord));
    printf("Insert the word to search: ");
    scanf("%s", app->word);
    app->totalOccurences = 0;
    app->p = head;
    app->next = NULL;

    if(start == NULL){
        tail = start = app;
    }else{
        tail = tail->next = app;
    }
    printf("Do you want to insert another word? (Y/N): ");
    scanf(" %c", &ch);
}while(ch == 'y' || ch == 'Y');

w = start; //pointer back to the top of the fWord structure

//traverse all the structure and execute the algorithm
while(w != NULL){
    while(w->p != NULL){
        fp = fopen(w->p->path, "r");
        if(fp == NULL){
            fprintf(stderr, "Cannot open %s, exiting. . .\n", w->p->path);
            exit(1);
        }

        int countLine = 0;
        w->p->fileOccurrences = 0;
        endOfLineDetected = 0;

        while(!endOfLineDetected){
            line2 = getLineOfAnySize(fp,128,&endOfLineDetected,&nrOfCharRead);
            int n = strlen(line2);
            int m = strlen(w->word);
            w->p->fileOccurrences = w->p->fileOccurrences + KMP(line2, w->word, n, m, countLine, w->p);
            countLine = countLine + 1;
        }   

        w->totalOccurences = w->totalOccurences + w->p->fileOccurrences;
        w->p->position = getHead(); // //pointer back to the top of the  fPosition structure
        w->p = w->p->next;
        fclose(fp);
    }
    w->p = head; //pointer back to the top of the fPath structure
}

w = start; //pointer back to the top of the fWord structure

//traverse all the structure and print out the occurrences and their position
while(w != NULL){
    w->p = head;
    printf("WORD %s \r\n", w->word);
    printf("TOTAL %d \r\n", w->totalOccurences);
    while(w->p != NULL){
        printf("FILE %s \r\n", w->p->path);
        printf("OCCURENCES %d   \r\n", w->p->fileOccurrences);
        while (w->p->position != NULL){
            printf("%d %d\r\n", w->p->position->line, w->p->position->character);
            w->p->position = w->p->position->next;
        }
        w->p = w->p->next;
    }
    w = w->next;
}

printf("\r\n"); //the file ends with an empty line

return 0;
}

//method used for read line by line a file
char * getLineOfAnySize(FILE* fp, size_t typicalSize, int *endOfLineDetected,size_t *nrOfCharRead){ 
char *line;       // buffer for our string
int ch;           // we will read line character by character
size_t len = 0;   // number of characters read (character counter)
size_t lineSize = typicalSize;  // initial size of the buffer allocated for the line
*nrOfCharRead = 0;

if(!fp) return NULL; // protection

// allocating the buffer
line = realloc(NULL, sizeof(char)*lineSize); // expected size of the line is up to typicalSize

if (!line) return line; // protection, if we fail to allocate the memory we will return NULL

while (1) { // loop forever     
    ch = fgetc(fp);       // getting character by character from file

    if (ch == '\n') break; // end of line detected - breaking the loop 
    if( ch == EOF)  {
        *endOfLineDetected = 1;
        break; // end of file detected - breaking the loop
     }

    line[len++] = ch;     // store the character in the line buffer, increase character counter

    if (len == lineSize){ // we reached the end of line buffer (no more room)

        lineSize = lineSize + 64; // we have to increase the line size 
        line = realloc(line, sizeof(char)*(lineSize)); // line buffer has new size now

        if (!line) return line; // if we fail to allocate memory we will return NULL
    }
    if( (len == 0) && *endOfLineDetected){ // empty file
        *endOfLineDetected = 1;
        break; 
    } 
}


line[len++] ='\0';  // ending the string (notice there is no '\n' in the string)
*nrOfCharRead = len;

return line;       // return the string
}
#include "kmp.h"

char * getLineOfAnySize(FILE* fp, size_t typicalSize, int *endOfLineDetected,size_t *nrOfCharRead);
#include "kmp.h"

fPosition *head = NULL;
fPosition *current = NULL;

// Function to implement KMP algorithm
int KMP(const char* X, const char* Y, int m, int n, int line, fPath *app){

int count = 0;

// next[i] stores the index of next best partial match
int next[n + 1];

for (int i = 0; i < n + 1; i++)
    next[i] = 0;

for (int i = 1; i < n; i++){
    int j = next[i + 1];

    while (j > 0 && Y[j] != Y[i])
        j = next[j];

    if (j > 0 || Y[j] == Y[i])
        next[i + 1] = j + 1;
}

for (int i = 0, j = 0; i < m; i++){
    if (*(X + i) == *(Y + j)){
        if (++j == n){
            count = count + 1; //count the occurrences of the string in this file   
            fPosition *node = malloc (sizeof(fPosition));
            node->line = line; //the current line
            node->character = i - j + 1; //the shift in which occurs
            node->next = NULL;

            if(head == NULL){
                current = head = node;
            }else{
                current = current->next = node;
            }

            app->position = current;

        }
    }
    else if (j > 0) {
        j = next[j];
        i--;    // since i will be incremented in next iteration
    }
}

    return count; //return the number of occurences found
}

//take the pointer back to the top of fPosition
fPosition * getHead(){ 
     fPosition *app = head;
     head = NULL;
     return app;
}
#include<stdio.h>
#include<stdlib.h>
#include<string.h>

struct filePath{
char *path; //the file path
struct filePath *next;
};

struct OccurrencesPosition{
int line; //line in which an occurrence is founded
int character; //shift at which the occurrences comes

struct filePath pathInfo;

struct OccurrencesPosition *next; //pointer to the next occurrences
};

struct fileWord{
char word[50]; //the string to search
int totalOccurences; //the total occurrences of the string

int fileOccurrences; //the occurrences of each file
struct OccurrencesPosition *position; //pointer to the linked list which tracks all the occurrences and their positions

struct fileWord *next; //pointer to the next word
};

typedef struct filePath fPath; 
typedef struct fileWord fWord;
typedef struct OccurrencesPosition fPosition;

fPosition * getHead();


int KMP(const char* X, const char* Y, int m, int n, int line, fPath *app);
您的设计应如下所示

struct filePath{
    char *path; //the file path
    struct filePath *next;
};

struct OccurrencesPosition{
    int line; //line in which an occurrences is founded
    int character; //shift at which the occurrences comes

    struct filePath pathInfo;

    struct OccurrencesPosition *next; //pointer to the next occurrences
};

struct fileWord{
    char word[50]; //the string to search
    int totalOccurences; //the total occurrences of the string

    int fileOccurrences; //the occurrences of each file
    struct OccurrencesPosition *position; //pointer to the linked list which tracks all the occurrences and their positions

    struct fileWord *next; //pointer to the next word
};

对你的术语有点吹毛求疵:C没有“类”。你所谓的类是一个文件。您有两个源文件(
find.c
kmp.c
)和两个头文件(
find.h
kmp.h
)。编辑正确,谢谢!如果没有任何有意义的变量名称,调试代码太多。不清楚什么是不正确的。请显示示例输入的预期输出。如您在输入文件中所看到的。“abc”总共是6个,文件是3个,但是程序在这两种情况下都会打印出“ac”。谢谢,为了解决这个问题,我应该如何更改代码?@gianfranco将位置信息作为
fword
的一部分进行维护。请您简要说明我应该如何更改程序?@gianfranco我已经给了您设计的外观,请相应地更新您的代码。我会尽快完成。多谢各位