【问题标题】:Trouble with linked lists链表的问题
【发布时间】:2012-04-10 01:04:17
【问题描述】:

我正在制作文件中出现的单词的链接列表(不重复)以及它们首先出现的行。我完成了我认为最困难的部分(在跟踪行的同时解析文件),但我相信我现在在我的一种方法中遇到了问题,我无法弄清楚如何解决。我的代码在两个文件中,但我只在代码中包含有问题的方法以及驱动程序。 (我尝试使用 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;
}

【问题讨论】:

    标签: c list linked-list


    【解决方案1】:

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

    调用应如下所示:

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

    附录:

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

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

    【讨论】:

    • 我解决了这个问题,现在我遇到了一个段错误。
    • 您当前的函数正在将当前指针推进到 while 循环的顶部而不是底部。
    • 谢谢。我也意识到标题不正确!我遗漏了返回值!应该解决我的一个逻辑问题。
    【解决方案2】:

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

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

    fgets() 附加空终止符,所以你不需要自己做。

    【讨论】:

      【解决方案3】:
      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;
          }
      

      这太丑了。您不需要自己终止 null,但如果您想删除换行符,那么您还应该确保为您的行号计算换行符...

      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。整个代码部分看起来都是附加的,缺乏适当的缩进和周围的上下文使得它几乎无法理解。我不得不认为您应该将所有这些代码分离到它们自己的例程中,使用硬编码测试彻底测试它们,并确保它在尝试将其连接到更大的程序之前完美运行。 (这实际上也适用于第一部分——看起来它会从一些孤立和定向的测试中受益。)

      【讨论】:

      • 我试图测试它实际上是在使用打印循环制作列表。
      猜你喜欢
      • 2021-01-13
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多