You wanted to pass in a string typed in by the user.
I was trying to write a function, which was originally going to receive user input (taken with fgets
) as an argument. I have put that aside now, and just decided to give the function a single argument.
This explains why you pass in a char *
to your function. The input value was originally going to be read from fgets
. In your program, you passed in the name of your variable.
bare example;
/* ... */
print_info("example");
To do a dynamic lookup on a symbol name, use dlsym
.
As I suggested in comments, if you want to be able to look up the name of a variable to find the associated object, you can use dlsym
so long as you are on a POSIX system (like Linux). For example:
// Need to inlcude <dlfcn.h> and link with -ldl
// Make local variables findable with -rdynamic
void print_info(char *name)
{
bare *p = dlsym(0, name);
if (p != NULL)
printf("The hp of %s is %d", p->name, p->hp);
else
printf("%s not found!\n", name);
}
So long as you include <dlfcn.h>
and use -ldl
when linking the program, and you make your symbol table visible (with -rdynamic
on GCC), the program will find the pointer to your example
variable. (Try it online!)
But you probably meant to do a lookup by name
.
However, you seemed to have mixed some things up. Usually, the user will not care what names you have used for the variables in your program. You would never expect fgets
to give you "example"
because that is not what the user would type in.
You probably meant to search for the bare
record that matches the name parameter of bare
. In your case, "John"
.
print_info("John");
Normally, you would have a table of bare
s that you would look over and check for a match. However, in your simplified example, there is only one to check.
bare * find_bare(char *name)
{
if (strcmp(name, example.name) == 0) return &example;
return NULL;
}
void print_info(char *name)
{
bare *p = find_bare(name);
if (p != NULL)
printf("The hp of %s is %d", p->name, p->hp);
else
printf("%s not found!\n", name);
}
It isn't hard to create and search a table of bare
.
In this case, you could probably simple create an array of bare
to represent your collection that you would search over.
#define BARE_TABLE_SIZE 50
bare table_example[BARE_TABLE_SIZE];
Assuming you add the code to populate your table, you could use a simple loop to search for a matching name.
bare * find_bare(char *name)
{
for (int i = 0; i < BARE_TABLE_SIZE; ++i)
{
if (strcmp(name, table_example[i].name) == 0)
return &table_example[i];
}
return NULL;
}
Your example.name
was an uninitialized pointer.
Finally, the most egregious error in your program is the attempt to call strcpy
on an uninitialized pointer. One solution is to allocate new memory to hold the new name and assign the location of the new name to the pointer. POSIX systems (like Linux) supply a function called strdup
that creates a copy of the input for you, in newly allocated memory.
example.name = strdup("John");
Since the memory is allocated by malloc
, you would need to call free
on the pointer if example
is ever recycled for a new name.