lata27
lata27

Reputation: 1

find words that match user input with strstr

In my register, I want to find all the words that match user input and display them.

For example if I have words like redapple, rottenapple, apple, banana in my register.

And user inputs apple I want to be able to dispaly redapple, rottenapple, apple and their itemnumber and inventory balance. I cannot display in the right way and cannot figure it why, have tried different way and I will post my last try. Thank you!

void search(Car a[],int nr){

    char ItmName[50];

    int i;
    while(1){
       
        printf("Type item name (q for menu): ");
        scanf("%s%*c", &ItmName);
   
        if(strcmp(ItmName,"q")==0){
            return;
        }else{
            for(i=0;i<nr;i++){
               char *word = strstr(a[i].name,ItmName);
                 for(i=0;i<nr;i++)
                   if(word==itemN){
                   printf("%d\t\t%s\t\t%d\n", a[i].itemNmr, a[i].name, a[i].inventory);
            }
            return;
        }
    
        }
    }
}

Upvotes: 0

Views: 96

Answers (1)

Oka
Oka

Reputation: 26385

Your nested loop use the same control variable, i, and continuation condition, which ensures only one iteration of the outer loop occurs.

The contents of the loop make little sense. You repeatedly compare a pointer to the first element of the input buffer (itemN; pressumably itemName) against the pointer value returned by strstr, after it looks through the name field of only the first element of the a array for the substring provided in itemName.

Rewritten verbosely, this reads as

for (i = 0; i < nr; i++) {
    for (i = 0; i < nr; i++) {
        if (strstr(a[0].name, itemName) == &itemName[0]) {
            printf(/* some information */);
        }
    }
}

which hopefully you can see makes no sense. A pointer value that points to an element of a[0].name will never be equal to the pointer value that points to the first element of itemName - as that would require their memory to overlap somehow.


In any case, this should not require any nested loops, as this can be done with a linear search of your array of structures.

First suggestion: move the user input to outside the function. Make search accept a third argument, a string to search for in each structures name. Separately (and repeatedly) take user input and then call this function.

Second suggestion: forget scanf exists entirely. Use fgets (and sscanf if you need to extract formatted data from the string).

Here's a cursory example of a linear search function:

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

typedef struct {
    char name[128];
    unsigned inventory;
} Car;

void search(Car *cars, size_t length, const char *query)
{
    for (size_t i = 0; i < length; i++)
        if (strstr(cars[i].name, query))
            printf("NAME: [%s]\tQUANT: [%u]\n", cars[i].name, cars[i].inventory);
}

int main(void)
{
    Car cars[] = {
        { "redapple", 10 },
        { "rottenapple", 7 },
        { "foo", 4 },
        { "bar", 15 },
        { "candyapple", 11 }
    };

    size_t len = sizeof cars / sizeof *cars;

    while (1) {
        char buf[512];

        printf("Enter a search string (. = exit): ");
        fflush(stdout);

        if (!fgets(buf, sizeof buf, stdin))
            return 1;

        if ('.' == *buf)
            return 0;

        /* remove any trailing CRLF */
        buf[strcspn(buf, "\r\n")] = '\0';

        search(cars, len, buf);
    }
}

Upvotes: 0

Related Questions