【问题标题】:strange value when print linked list values in c在c中打印链表值时出现奇怪的值
【发布时间】:2017-11-03 01:47:59
【问题描述】:

我使用链表在 C 中创建了一个应用程序,该应用程序从标准输入中逐行获取数据,并将每个单词输入到链表中,最后打印所有这些单词而没有任何重复,所以我制作了这个代码

//linked list
typedef struct NODE Node;
struct NODE{
  char *item;
  Node *next;
};
 //insert function
bool insert(Node** head_ref, char *new_string)
{
    /* allocate node */
struct NODE* new_node = (struct NODE*) malloc(sizeof(struct NODE));

/* put in the data  */
new_node->item = new_string;

/* link the old list off the new node */
new_node->next = (*head_ref);

/* move the head to point to the new node */
(*head_ref) = new_node;
return true;
}
// tells us whether or not the given string is in the list
bool search(struct NODE *head, char *target)
{
    struct NODE *current = head;
    while (current != NULL)
    {
        if (current->item == target)
            return true;
        current = current->next;
    }
    return false;
}
// declare of the linked list 
Node *LinkedList = NULL;
//function used to read the stander input from the user
void loadFile()
{
#define LINE_SIZE 256
  char input[LINE_SIZE];
  char *token = NULL;

  while ( fgets( input, LINE_SIZE, stdin ) )
  {
    // parse the data into separate elements
    token = strtok( input, " \t\n" );
    while ( token )
    {
        if (!search(LinkedList, token)) {
            insert(&LinkedList, token);
            //puts("insert");
        }
        else {
            //printf("Not insert\n");
        }


      token = strtok( NULL, " \t\n" );
    }
  }
}

这个函数打印列表中的所有单词

void Print(Node* head)
{
    Node *current = head;
    while (current != NULL)
    {
        printf("%s\n", current->item);
        current = current->next;
    }
}

当我在最后打印单词时,它给了我主要的奇怪字符

int main()
{
  loadFile();
  Print(LinkedList);

  return 0;
}

我在 windows 上使用 cntrl + Z 停止输入

【问题讨论】:

  • 预期输出和实际输出的示例是什么?
  • 关于:struct NODE { char *item; Node *next; }; 最好将Node *next;替换为struct NODE *next;,并将typedef放在结构体定义后
  • 在调用任何堆分配函数(malloc、calloc、realloc)时 1) 始终检查 (!=NULL) 返回值以确保操作成功。 2)返回的类型是void*,可以赋值给任何指针,强制转换只会使代码混乱,使其更难理解、调试等。
  • 在函数中:insert(),这个语句:new_node->item = new_string;导致所有item指针指向输入缓冲区的开始(所以它们都指向同一个东西)他们每个人都需要指向唯一的字符串。建议:new_node->item = strdup(new_string); if( !new_node->item ) { // then strdup failed, handle error, cleanup, call exit()` }`
  • 发布的代码无法将分配的内存返回到堆。 (这通常是通过调用 free() 来完成对从调用 malloc(), calloc()` 的调用返回的每个指针。)不进行调用的结果是内存泄漏。

标签: c pointers linked-list token c-strings


【解决方案1】:

我认为这是因为您实际上并没有为项目分配空间,您只是在重用同一个缓冲区。 insert(&LinkedList, strdup(token));

你也在比较指针而不是字符串

if (current->item == target)

if (strcmp(current->item, target)==0)

虽然有当前的错误,但它可能真的可以工作!

【讨论】:

    【解决方案2】:

    以下建议代码:

    1. 干净编译
    2. 将 cmets 中突出显示的所有问题更正为问题
    3. 正确检查错误
    4. 记录包含每个头文件的原因
    5. 一致缩进代码,每个缩进级别为 4 个空格
    6. 包含适当的水平间距:括号内、逗号后、分号后、C 运算符周围。
    7. 通过一个空行分隔代码块(for、if、else、whle、do...while、switch、case、default)
    8. 执行所需的功能

    现在建议的代码:

    //linked list
    #include <stdio.h>    // fgets(), printf()
    #include <stdlib.h>   // malloc(), exit(), EXIT_FAILURE
    #include <stdbool.h>  // bool, true, false
    #include <string.h>   // strtok(), strdup()
    
    #define LINE_SIZE 256
    
    
    struct NODE
    {
      char *item;
      struct NODE *next;
    };
    typedef struct NODE Node;
    
    
    // declare of the linked list
    Node *LinkedList = NULL;
    
    
    // prototypes
    void insert( Node **head_ref, char *new_string );
    bool search( Node *head, char *target );
    void Print ( Node *head );
    void loadFile( void );
    
    
     //insert function
    void insert( Node **head_ref, char *new_string )
    {
        /* allocate node */
        struct NODE* new_node =  malloc( sizeof(struct NODE) );
        if( !new_node )
        {
            perror( "malloc failed" );
            // TODO: cleanup
            exit( EXIT_FAILURE );
        }
    
        // implied else, malloc successful
    
        /* put in the data  */
        new_node->item = strdup( new_string );
        if( !new_node->item )
        {
            perror( "strdup failed" );
            // TODO: cleanup
            exit( EXIT_FAILURE );
        }
    
        // implied else, strdup successful
    
        /* link the old list off the new node */
        new_node->next = (*head_ref);
    
        /* move the head to point to the new node */
        (*head_ref) = new_node;
    }
    
    
    // tells us whether or not the given string is in the list
    bool search( Node *head, char *target )
    {
        struct NODE *current = head;
    
        while ( current != NULL )
        {
            if ( strcmp( current->item, target) == 0 )
                return true;
    
            current = current->next;
        }
    
        return false;
    }
    
    
    //function used to read 'stdin' from the user
    void loadFile()
    {
        char input[ LINE_SIZE ];
        char *token = NULL;
    
        while ( fgets( input, LINE_SIZE, stdin ) )
        {
            // parse the data into separate elements
            token = strtok( input, " \t\n" );
    
            while ( token )
            {
                if ( !search( LinkedList, token ) )
                {
                    insert( &LinkedList, token );
                    //puts("insert\n");
                }
    
                else
                {
                    //printf("Not insert\n");
                }
    
                token = strtok( NULL, " \t\n" );
            }
        }
    }
    
    
    //this function to print all the words in the list
    void Print( Node* head )
    {
        Node *current = head;
    
        while ( current != NULL )
        {
            printf( "%s\n", current->item );
            current = current->next;
        }
    }
    
    
    //when i print the words at the end it give me strange characters this my main
    int main( void )
    {
        loadFile();
        Print( LinkedList );
    
        return 0;
    }
    

    程序的简单运行结果如下:

    1
    3
    5
    5
    4
    2
    0   (at this point, used <ctrl-d> (linux) to end the input
    0
    2
    4
    5
    3
    1
    

    程序的第二次简单运行

    first second second first third forth
    forth
    third
    second
    first
    

    【讨论】:

      猜你喜欢
      • 2018-09-29
      • 2013-06-30
      • 1970-01-01
      • 2021-02-06
      • 1970-01-01
      • 2012-11-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多