链接列表有问题

时间:2012-04-10 01:04:18

标签: c list linked-list

我正在制作一个出现在文件中的单词的链接列表(没有重复)以及它们首次出现的行。我完成了我认为困难的部分(解析文件同时跟踪线条),但我相信我现在在我的一种方法中遇到问题,我无法弄清楚如何修复。我的代码有两个文件,但我只在代码和驱动程序中包含问题。 (我尝试使用GDB,我认为我使用它是错误的,因为它一直说它无法找到文件而且它不会运行。)

int main(int argc, char **argv){
file = fopen(argv[1],"r");
/*struct fileIndex *fIndex = NULL;*/ /*put this in header file??*/
fIndex = NULL;
delimiters = " .,;:!-";/*strtok chars to seperate*/
rewind(file);
int buffer = 65;
char str[buffer+1];/*where the lines are being stored*/
char *token, *cp;
int i;
int len;
while((fgets(str, buffer, file))!=NULL){/*inserting lines*/
for(i=0; i<buffer; i++){
    if(str[i]=='\n'){
    str[i]= '\0';
    break;
    }
}
len = strlen(str);
cp = xerox(str);
token = strtok(cp, delimiters);
/*if(token!=NULL)
printf("The word is %s\n", token);*/
    if(!present(fIndex, token)&&(token!=NULL)){
        insert(fIndex, i+1, token);
    }
    while(token!=NULL){
        token = strtok(NULL, delimiters);
        /*if(token!=NULL)
        printf("The word is %s\n", token);*/
        if(!present(fIndex, token)&&(token!=NULL)){
            insert(fIndex, i+1, token);
        }

    }
}
fclose(file);
struct fileIndex *root;
root = fIndex;

while(root != NULL){
printf("The string is %s and on line %d\n", root -> str, root -> lineNum);
root = root -> next;
}


free(fIndex);
free(cp);

return 0;
}







struct fileIndex *insert(struct fileIndex *head, int num, char *insert){
struct fileIndex* newnode = malloc(sizeof(struct fileIndex));
if(newnode==NULL)
exit(1);

newnode -> str = insert;
newnode -> lineNum = num;

newnode -> next = head;
return newnode;
}

编辑:我也在考虑我的方法中的一个问题,即检查一个单词是否已存在。我把一个打印声明放在哪里,只有在插入单词并打印所有单词时才打印。打印列表末尾的小循环不打印,我认为它在第一次到达并且从不循环时达到NULL。

present(struct fileIndex* fIndex, char *findIt){/*finds if word is in structure*/
struct fileIndex* current = fIndex;
while(current!=NULL){
current = current -> next;
if(strcmpigncase(current -> str, findIt)==0){
    return current -> lineNum;
}
}
return 0;
}

3 个答案:

答案 0 :(得分:2)

insert函数返回新列表,但您没有在代码中使用返回值。

调用应如下所示:

fIndex = insert(fIndex, i+1, token);

附录:

此外,在检查它是否为NULL之前,您正在使用令牌。它应该是这样的:

if((token!=NULL) && !present(fIndex, token)){
    fIndex = insert(fIndex, i+1, token);
}

答案 1 :(得分:2)

你应该经常检查fopen()是否成功。

if(file == NULL) {
printf("Error fopen");
exit(1);
}

fgets()附加null终止符,因此您不需要自己执行此操作。

答案 2 :(得分:0)

file = fopen(argv[1],"r");

您忘记检查fopen()是否成功。每个fopen(3)后面都应跟代码类似:

if (!file) {
    fprintf(stderr, "unable to open %s\n", argv[1]);
    perror(argv[0]);
    exit(EXIT_FAILURE);
}

如果你能比退出更优雅地处理错误(回退到默认值?),那么你可能希望这样做。

for(i=0; i<buffer; i++){
    if(str[i]=='\n'){
    str[i]= '\0';
    break;
    }

这非常难看。您不需要自行终止,但如果您想删除换行符,那么您还应确保计算行号的换行符...

struct fileIndex *root;
root = fIndex;

while(root != NULL){
    printf("The string is %s and on line %d\n", root -> str, root -> lineNum);
    root = root -> next;
}


free(fIndex);
free(cp);

我从未真正看到fIndex分配 - 它只是一个指针,并且您在开始时分配了它NULL。这整段代码看起来很明显,缺乏适当的缩进和周围环境使得几乎无法理解。我必须认为你应该把所有这些代码分成他们自己的例程,使用硬编码测试彻底测试它们,并确保它在尝试将它连接到更大的程序之前完美地工作。 (这实际上也适用于第一部分 - 看起来它会受益于一些孤立和有针对性的测试。)