Home > OS >  Can someone help me with structs in C?
Can someone help me with structs in C?

Time:01-03

Any ideas why this is only printing not found. The idea of course is that the user types a name and it prints their name and number. Anything helps of course! Sorry I am a beginner and I am having quite a few issues. I chose C to learn first so that it hopefully gets easier from here.

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

typedef struct
{
    char* name;
    char* number;
}
person;

int main(void)
{
    person people[3];
    
    people[0].name = "sam";
    people[0].number = "99912222";
    
    people[1].name = "tom";
    people[1].number = "11122222";

    people[2].name = "harry";
    people[2].number = "12299933";
    
    
    char boot;
    printf("Enter: ");
    scanf("%c", &boot);

    for(int i = 0; i < 3; i  )
    {
        if(strcmp(people[i].name, &boot) == 0)
        {
            printf("%s=%s\n",people[i].name, people[i].number);
            return 0;
        }
    }
    printf("Not Found\n");
    return 1;
}

CodePudding user response:

%c means get a single character from input. Therefore, if you enter 'abc', all you will get is 'a'.

Another extremely important thing is that, boot is declared as a single char, i.e. char boot;.

A char occupies 1 byte in memory. So, when you pass &boot(pointer to the address of boot) to strcmp(), it will first check the length of the arguments. How will it find its length? Simple, by looking upto the '\0' character in memory. Since you have declared boot as a single char, it only contains the first character of the input. Hence, strcmp() will potentially access memory that probably shouldn't be accessed. This results in Undefined Behaviour. To avoid it, you will need to keep boot atleast n bytes where n > 1 and the n'th byte must be a null byte if there are no other null bytes present in between the 1st and the n'th byte.

Short note: As far as I know, Pointers point to the address of the first byte of what you assign it to. So,

...
// imagine buf[0] is 0x121 and buf[1] is 0x122
char buf[2];
char *ptr = buf;
// ptr will point to 0x121
...

Try:

...
    int nbytes_to_accept = 128;
    char boot[nbytes_to_accept   2];
    /* name (nbytes_to_accept)  
     * [Extra character to check if name is higher than the max]  
     * LF/NULL
     * = nbytes_to_accept   2
     */
    printf("Enter: ");
    fgets(boot, sizeof boot, stdin);
    boot[strcspn(boot, "\n")] = '\0'; // remove LF, as we don't need it
    if (strlen(boot) > nbytes_to_accept) {
        printf("ERROR: Name cannot be larger than 128 characters.\n");
        return 1;
    }

    /* Make sure to properly get the size of
     * the elements of the list, without
     * doing a sizeof on a pointer, if this
     * list becomes extendable and stuff.
     * One way would be to store the size somewhere
     */
    for(int i = 0; i < 3; i  )
    {
        if(strcmp(people[i].name, boot) == 0)
        {
            printf("%s=%s\n",people[i].name, people[i].number);
            return 0;
        }
    }
    printf("Not Found\n");
    return 1;
}
  • Related