-1

I want to search in a linked list that stores names, I created the function but the printf statements that output if the element was found or not don't print anything. The code seems correct, I tried to debug it line by line but I couldn't figure it out.

Here's the function:

void exist(Name **head) {
    Name *ptr = malloc(sizeof(Name));
    printf("Enter your name to search:\n");
    fgets(ptr->name, 50, stdin);
    Name *p = *head;
    bool found = false;
    while (p != NULL) {
        if (strcmp(ptr->name, p->name) == 0) {
            printf("Node found\n");
            found = true;
            break; 
        }
        p = p->next;
    }
    if (!found)
        printf("Node not found\n");
}

and the structure:

 typedef struct Name { 
     char name[50];
     struct Name *next;
 } Name;

this is the main function:

int main() {
    Name *head = NULL;
    Name *newNode = malloc(sizeof(Name));
    strcpy(newNode->name, "John");
    newNode->next = NULL;
    exist(head);
}
chqrlie
  • 131,814
  • 10
  • 121
  • 189
Jane
  • 7
  • 4
  • 3
    It should be `exist(&head)`. – Barmar Apr 20 '23 at 22:59
  • But `head` is null. You need `head = newNode;` – Barmar Apr 20 '23 at 23:00
  • 1
    There's no reason why `exist()` should receive the argument as `Name**`. That's only need for functions that need to change the caller's pointer. – Barmar Apr 20 '23 at 23:01
  • 2
    There's no need for `exist()` to allocate a `Name` structure just to hold the name you're searching for. It can just use `char search[50];` You also never `free(ptr);` – Barmar Apr 20 '23 at 23:02
  • 2
    You're not removing the newline from the end of `ptr->name`. See https://stackoverflow.com/questions/2693776/removing-trailing-newline-character-from-fgets-input – Barmar Apr 20 '23 at 23:03
  • Make sure you always fix your pointer type mismatch warnings *before* attempting to run your code. Your post says "it didn't print anything", which implies you tried to run the code. Did you declare `exist` before calling it? If you did, then you should have gotten a warning which should have been fixed before attempting to run code with known bugs. If not, then in a way that's even worse: Never call a function that you haven't declared. – Tom Karzes Apr 20 '23 at 23:22
  • If you search a certain book on a shelf, do you start from manufacturing an empty book? That's what `Name *ptr = malloc(sizeof(Name));` does. Also a function that finds something shouldn't do any I/O. Also you absolutely don't need a two-star `**head`, the only thing you do with it is `Name *p = *head;`. Hence `bool exist(Node* head, const char* name)`. Handle I/O outside of `exist`. – n. m. could be an AI Apr 21 '23 at 08:16

1 Answers1

2

The function fgets can append to the entered string the new line character '\n' that corresponds to the pressed Enter key that you should remove. For example

void exist(Name **head){
    Name *ptr = malloc(sizeof(Name));
    printf("Enter your name to search:\n");
    fgets(ptr->name, 50, stdin);
    ptr->name[ ( strcspn( ptr->name, "\n" ) ] = '\0';
    //...

But in any case the function as is does not make sense.

For starters it produces a memory leak due to this statement

Name *ptr = malloc(sizeof(Name));

There is no any sense to allocate a node within the function. Moreover the call of malloc can fail. In this case such a simple function will have undefined behavior.

The function shall not ask any question to the user and shall not issue any message. It is the caller of the function will decide whether to issue a message or to do something else based on the result of a function call.

Also it is unclear why the pointer to the head node is accepted through a pointer to it while the function is called like

exist(head);

instead of

exist(&head);

And from the function declaration

void exist(Name **head);

it is entirely unclear what does exist. Is it the node pointed to by the pointer head that exists or something else?:)

The function can be declared and defined the following way

int exist( const Name *head, const char *name )
{
    while ( head != NULL && strcmp( head->name, name ) != 0 )
    {
        head = head->next;
    }

    return head != NULL;
}

In main you can write

int main( void ) 
{
    Name *head = malloc( sizeof( Name ) );
    strcpy( head->name, "John" );
    head->next = NULL;

    char name[50];

    printf("Enter your name to search:\n");

    fgets(name, sizeof( name ), stdin);
    name[ ( strcspn( name, "\n" ) ] = '\0';
    
    if ( exist( head, name ) )
    {
        puts("Node found");
    }
    else
    {
        puts("Node not found");
    }

    free( head );
}
Vlad from Moscow
  • 301,070
  • 26
  • 186
  • 335