【问题标题】:Issue when comparing a value in a linked list in C比较 C 中链表中的值时的问题
【发布时间】:2015-01-19 02:50:04
【问题描述】:

我正在使用 C 语言编写一个“简单”程序,在该程序中,我们创建了一个链表,其结构类似于电影,其中存储了标题、制作年份、评级 (1-5) 和指向下一个节点的指针。我们不允许在这个结构中添加任何东西,或者定义函数。

除此之外,我们(出于某种原因)需要在 main() 的主体中编写整个链表,这样就给问题增加了一层意大利面。无论如何,在这个程序中,我们应该让用户输入“U”来更新或输入“S”来搜索电影。更新符合您的预期,您输入标题、年份、评级。由此,我们应该将节点插入到链表的end

我们的搜索应该遍历这个链接列表,如果找到匹配项,应该打印出电影、标题和年份。

虽然我的代码的更新部分有效,但我似乎无法让搜索工作。我正在使用一个名为 temp 的电影结构,它从 head 开始并遍历列表以尝试找到电影。通过 printf 运行一些测试后,我发现 temp 无论如何都只是一个空节点,无论我输入什么电影。

我假设这与我调用 malloc 的方式有关?还是与未正确分配节点有关?老实说,我不确定,不幸的是,实验室的 TA 也不知道出了什么问题 D:

这是我的代码:

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

struct movie_node {
        char title[250];
        int year;
        unsigned char rating;
        struct movie_node *next;
};

typedef struct movie_node movie;

int main() {

        // variables
        int loop = 1;
        movie *head = NULL; // represents first
        movie *current; // represents the last node
        movie *temp; // used for traversing the linked list
        head = malloc(sizeof(movie));
        int amountOfMovies = 0; // increment after each addition
        char choice; // either 'u' (update) or 's' (search)
        // ask user for input
        while(loop) {

                printf("%d Movie(s) in the database. Update or search (U/S): ", amountOfMovies);
                scanf(" %c", &choice);
                /* CHOICE 1, UPDATE */
                if(choice == 'U') {

                        // case 1, head is null, we must create a new node
                        if(head == NULL) {
                                // get input
                                printf("Name of the movie: ");
                                scanf(" %[^\n]%*c", head->title);
                                printf("Year: ");
          scanf("%d", &head->year);
                                printf("Rating: ");
                                scanf("%hhu", &head->rating);
                                head->next = NULL;
                                head = current; // set head to point to current
                        } else {
                                current = head;
                                // need to find where current is
                                while(current != NULL) {
                                        current = current->next;
                                } // end while
                                // current is now at the null position, indicating empty node
                                current = malloc(sizeof(movie)); // allocate mem
                                // get user input
                                printf("Name of the movie: ");
                                scanf(" %[^\n]%*c", current->title);
                                printf("Year: ");
                                scanf("%d", &current->year);
                                printf("Rating: ");
                                scanf("%hhu", &current->rating);
                                current->next = NULL;
                        } // end else
                        // output movie
                        printf("Movie \"%s\" is added to the database.\n", current->title);
                        amountOfMovies++; // increment amount of movies in database
                } else if(choice == 'S') {
                /* CHOICE 2, SEARCH */
                        // temp string
                        char tempTitle[250];
                        // flag to let us know if we found something
                        bool found = false;
                        // temp linked list to traverse
                        temp = head;
                        temp = malloc(sizeof(movie));
                        // ask user for input
                        printf("Name of movie: ");
                        scanf(" %[^\n]%*c", tempTitle);
                        printf("NAME OF MOVIE IN HEAD: %s\n", temp->title);             // test, take out later
                        while(temp != NULL) {
                                printf("NAME OF CURRENT MOVIE TO COMPARE TO: %s\n", temp->title); // test
                                if(strcmp(temp->title, tempTitle) == 0) {
                                        // match
                                        printf("Year: %d\n", temp->year);
                                        printf("Rating: %hhu\n", temp->rating);
                                        found = true;
                                        break;
                                } else { // no match so far
                                        temp = temp->next;
                                        printf("HAVEN'T FOUND MATCH, NEXT TITLE TO CHECK IS: %s\n", temp->title); // test print
                                        found = false;
                                }  // end else
                        } // end while
                        if(found == false) { // no match confirmed
                                printf("Movie \"%s\" does not exist in the database.\n", tempTitle);
                        }
                } else { // choice is invalid
                        loop = 0; // exit
                } // end if-else

        } // end while
        // free all the nodes

        return 0;
}

注意:我唯一还没有实现的是释放内存.. 我不是百分百确定我应该如何完成它。

非常感谢任何帮助..

【问题讨论】:

  • 尝试为每个任务编写函数。这样您的代码将易于阅读和调试。
  • 您的代码包括:if(head == NULL) { printf("Name of the movie: "); scanf(" %[^\n]%*c", head-&gt;title); 这意味着您正在访问一个空指针,这是一个bad idea™。您应该只需要大量代码来进行输入。您可能需要创建一个函数来执行输入,并将指针传递给应读取数据的变量(结构)。您还应该针对在您的程序中输入“EOF”(control-D 或 control-Z)的用户强化您的​​代码(测试输入操作的结果)。
  • 程序执行temp = head;然后temp = malloc(sizeof(movie));。这个逻辑是不是毫无意义?

标签: c pointers struct linked-list malloc


【解决方案1】:

问题在于您的malloc() 电话。首先你要做:

movie *head = NULL;
// ...
head = malloc(sizeof(movie));

这意味着 head 不再为空,您将无法以您想要的方式插入第一部电影 - 将 malloc() 移动到其他位置。

其次,下面几行代码,你可以这样做:

current = head; // <- this is OK
// ...
current = malloc(sizeof(movie)); // allocate mem <- this is NOT OK, for the same reason as before

此外,您还可以阅读这样的电影标题:scanf("%249s", head-&gt;title)

如果你知道如何从那里出发,请告诉我。

除了代码中的问题之外,还有另一个问题:实验室的 TA 也不知道出了什么问题

【讨论】:

    【解决方案2】:

    样本修复

    movie *new_node(void){//aggregate the creation of a new node
        movie *node = malloc(sizeof(*node));//error check omit
        printf("Name of the movie: ");
        scanf(" %249[^\n]%*c", node->title);
        printf("Year: ");
        scanf("%d", &node->year);
        printf("Rating: ");
        scanf("%hhu", &node->rating);
        node->next = NULL;
        return node; 
    }
    
    int main() {
        int loop = 1;
        movie *head = NULL; 
        movie *current; 
        movie *temp; 
        //head = malloc(sizeof(movie));//"if(head == NULL) {" don't work 
        int amountOfMovies = 0; 
        char choice; 
    
        while(loop) {
            printf("%d Movie(s) in the database. Update or search (U/S): ", amountOfMovies);
            scanf(" %c", &choice);
    
            if(choice == 'U') {
                if(head == NULL) {
                    current = head = new_node();//need set to current
                } else {
                    current = head;
                    while(current->next != NULL) {//"current != NULL" can't link
                        current = current->next;
                    }
                    current = current->next = new_node(); 
                } 
                printf("Movie \"%s\" is added to the database.\n", current->title);
                amountOfMovies++; 
            } else if(choice == 'S') {
                char tempTitle[250];
                bool found = false;//need <stdbool.h>
                temp = head;
                //temp = malloc(sizeof(movie));//Unnecessary
                printf("Name of movie: ");
                scanf(" %249[^\n]%*c", tempTitle);
                //printf("NAME OF MOVIE IN HEAD: %s\n", temp->title);            
                while(temp != NULL) {
                    //printf("NAME OF CURRENT MOVIE TO COMPARE TO: %s\n", temp->title); 
                    if(strcmp(temp->title, tempTitle) == 0) {
                        printf("Year: %d\n", temp->year);
                        printf("Rating: %hhu\n", temp->rating);
                        found = true;
                        break;
                    } else { 
                        temp = temp->next;
                        printf("HAVEN'T FOUND MATCH, NEXT TITLE TO CHECK IS: %s\n", temp->title); 
                        //found = false;//Unnecessary
                    }  
                } 
                if(found == false) { 
                    printf("Movie \"%s\" does not exist in the database.\n", tempTitle);
                }
            } else { 
                loop = 0; 
            } 
        } 
        // free all the nodes
        return 0;
    }
    

    【讨论】:

      猜你喜欢
      • 2019-06-07
      • 1970-01-01
      • 2020-03-28
      • 2013-04-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-12-12
      • 1970-01-01
      相关资源
      最近更新 更多