c - 从列表中删除节点中保存的字符串

标签 c list

我创建了这个动态列表,我可以在其中输入字符串,该字符串将保存在列表的节点中,insert应该创建节点,为字符串分配内存并保存它,而 delete 应该接收节点中保存的字符串之一作为输入,删除它并释放它正在使用的内存。我在删除功能方面遇到了很多麻烦,它似乎收到了输入,但后来它不会删除节点,似乎找不到要删除的字符串,实际上我只收到“未找到”作为输出。我认为当我将要删除的字符串传递给函数时会发生错误,但我找不到它,任何人都可以给我一些建议吗?

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

// self-referential structure                       
struct listNode {                                      
   char *data; // each listNode contains a character 
   struct listNode *nextPtr; // pointer to next node
};

typedef struct listNode ListNode; // synonym for struct listNode
typedef ListNode *ListNodePtr; // synonym for ListNode*

// prototypes
void insert(ListNodePtr *sPtr, char *value);
char delete(ListNodePtr *sPtr, char  *value);
int isEmpty(ListNodePtr sPtr);
void printList(ListNodePtr currentPtr);
void instructions(void);
int main(void)
{ 
   ListNodePtr startPtr = NULL; // initially there are no nodes
   char item[20]; // char entered by user
   instructions(); // display the menu
   printf("%s", "? ");
   unsigned int choice; // user's choice
   scanf("%u", &choice);
   // loop while user does not choose 3
   while (choice != 3) { 
      switch (choice) { 
         case 1:
            printf("%s", "Enter a character: ");
            scanf("%s", item);
            insert(&startPtr, item); // insert item in list
            printList(startPtr);
            break;

     case 2: // delete an element
            // if list is not empty
            if (!isEmpty(startPtr)) { 
               printf("%s", "Enter character to be deleted: ");
               scanf("%s", item);
               // if character is found, remove it
               if (delete(&startPtr, item)) { // remove item
                  printf("%s deleted.\n", item);
                  printList(startPtr);
               } 
               else {
                  printf("%s not found.\n\n", item);
               } 
            } 
            else {
               puts("List is empty.\n");
            } 
            break;

         default:
            puts("Invalid choice.\n");
            instructions();
            break;
      } // end switch
      printf("%s", "? ");
      scanf("%u", &choice);
   } 
   puts("End of run.");
} 
// display program instructions to user
void instructions(void)
{ 
   puts("Enter your choice:\n"
      "   1 to insert an element into the list.\n"
      "   2 to delete an element from the list.\n"
      "   3 to end.");
}

// insert a new value into the list in sorted order
void insert(ListNodePtr *sPtr, char *value)
{ 
   ListNodePtr newPtr = malloc(sizeof(ListNode)); // create node

   if (newPtr != NULL) { // is space available
      newPtr->data= malloc(strlen(value)+1);
      strcpy(newPtr->data, value);
      newPtr->nextPtr = NULL; // node does not link to another node
      ListNodePtr previousPtr = NULL;
      ListNodePtr currentPtr = *sPtr;
      // loop to find the correct location in the list       
      while (currentPtr != NULL && value > currentPtr->data) {
         previousPtr = currentPtr; // walk to ...               
         currentPtr = currentPtr->nextPtr; // ... next node 
      }                                          
      // insert new node at beginning of list
      if (previousPtr == NULL) { 
         newPtr->nextPtr = *sPtr;
         *sPtr = newPtr;
      } 
      else { // insert new node between previousPtr and currentPtr
         previousPtr->nextPtr = newPtr;
         newPtr->nextPtr = currentPtr;
      } 
   } 
   else {
      printf("%s not inserted. No memory available.\n", value);
   } 
} 

// delete a list element
char delete(ListNodePtr *sPtr, char *value)
{ 
   // delete first node if a match is found
   if (value == (*sPtr)->data) { 
      ListNodePtr tempPtr = *sPtr; // hold onto node being removed
      *sPtr = (*sPtr)->nextPtr; // de-thread the node
      free(tempPtr); // free the de-threaded node
      return *value;
   } 
   else { 
      ListNodePtr previousPtr = *sPtr;
      ListNodePtr currentPtr = (*sPtr)->nextPtr;
      // loop to find the correct location in the list
      while (currentPtr != NULL && currentPtr->data != value) { 
         previousPtr = currentPtr; // walk to ...  
         currentPtr = currentPtr->nextPtr; // ... next node  
      } 
      // delete node at currentPtr
      if (currentPtr != NULL) { 
         ListNodePtr tempPtr = currentPtr;
         previousPtr->nextPtr = currentPtr->nextPtr;
         free(tempPtr);
         return *value;
      } 
   } 
   return '\0';
} 

// return 1 if the list is empty, 0 otherwise
int isEmpty(ListNodePtr sPtr)
{ 
   return sPtr == NULL;
} 


// print the list
void printList(ListNodePtr currentPtr)
{ 
   // if list is empty
   if (isEmpty(currentPtr)) {
      puts("List is empty.\n");
   } 
   else { 
      puts("The list is:");
      // while not the end of the list
      while (currentPtr != NULL) { 
         printf("%s --> ", currentPtr->data);
         currentPtr = currentPtr->nextPtr;   
      } 
      puts("NULL\n");
   } 
} 

最佳答案

您正在使用char[]字符数组来存储字符串 如果您这样做是为了比较值

value == (*sPtr)->data

那么你只是比较这些ptr的指针地址。

您需要比较值,因此必须使用strcmp函数来比较c样式字符串

strcmp(value,(*sPtr)->data)==0

 char delete(ListNodePtr *sPtr, char *value)
{ 
   // delete first node if a match is found
   if (strcmp(value,(*sPtr)->data)==0) {              //like this
      ListNodePtr tempPtr = *sPtr; // hold onto node being removed
      *sPtr = (*sPtr)->nextPtr; // de-thread the node
      free(tempPtr); // free the de-threaded node
      return *value;
   } 
   else { 
      ListNodePtr previousPtr = *sPtr;
      ListNodePtr currentPtr = (*sPtr)->nextPtr;
      // loop to find the correct location in the list
      while (currentPtr != NULL && strcmp(currentPtr->data,value)!=0) { 
         previousPtr = currentPtr; // walk to ...  
         currentPtr = currentPtr->nextPtr; // ... next node  
      } 
      // delete node at currentPtr
      if (currentPtr != NULL) { 
         ListNodePtr tempPtr = currentPtr;
         previousPtr->nextPtr = currentPtr->nextPtr;
         free(tempPtr);
         return *value;
      } 
   } 
   return '\0';
} 

关于c - 从列表中删除节点中保存的字符串,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51303109/

相关文章:

c - 使用已声明的未声明标识符 'k'

c - 如何使用 Netlink 套接字接收内核 uevents?

c - 有没有一种可移植的方法来找出 C11 实现支持哪些对齐方式?

c# - 如何在 4000 万词的列表中快速搜索?

regex - 如何将字符串与正则表达式列表进行匹配

java - 如何在 Java 中将 Map 转换为 List?

c - 从 C 套接字上的传入流中提取数据(字符串、字符等)

c - C 语言中 %di 说明符有什么作用?

python - 如何对列表中的连续重复项求和?

c++ - 运算符 [] 列出 cpp