I've been trying to create a binary search tree that sorts in alphabetical order according to their "company" name out of these structs with recursion for quite a while now. The movement through the structs to get the pointers to point to the right spots is confusing me a lot.
I'm getting these errors:
gcc -c tree.c
tree.c: In function ‘treeInsert’:
tree.c:34:11: error: request for member ‘entryPtr’ in something not a structure or union
tree.c:36:55: error: request for member ‘entryPtr’ in something not a structure or union
tree.c:38:12: error: request for member ‘right’ in something not a structure or union
tree.c:39:35: error: request for member ‘right’ in something not a structure or union
tree.c:43:12: error: request for member ‘left’ in something not a structure or union
tree.c:44:35: error: request for member ‘left’ in something not a structure or union
tree.c:47:3: warning: passing argument 1 of ‘printTree’ from incompatible pointer type [enabled by default]
In file included from tree.c:19:0:
tree.h:36:6: note: expected ‘struct treeNode *’ but argument is of type ‘struct treeNode ’
make: * [tree.o] Error 1
Here are the structs:
typedef struct companyEntryTag{
char * companyName;
char * companyDescription;
char * website;
char * streetAddr;
char * suiteNumber;
char * city;
char * state;
int zip;
double latitude;
double longitude;
} companyEntry;
typedef struct treeNodeTag{
companyEntry * entryPtr;
struct treeNodeTag * left;
struct treeNodeTag * right;
} treeNode;
typedef struct listNodeTag{
companyEntry * entryPtr;
struct listNodeTag * next;
} listNode;
I've tried a bunch of different solutions, but here is my current function I'm using to try to do this, that got the above error:
int treeInsert(listNode * list, treeNode ** rootPtr)
{
if(list == NULL){return -1;}
//Make the root next point to what list is
*rootPtr->entryPtr = list->entryPtr;
if(strcmp(list->next->entryPtr->companyName, rootPtr->entryPtr->companyName)==1)
{
rootPtr->right->entryPtr = list->next;
treeInsert(list->next, rootPtr->right->entryPtr);
}
else
{
rootPtr->left->entryPtr = list->next;
treeInsert(list->next, rootPtr->left->entryPtr);
}
printTree(rootPtr);
return 0;
}
I'm not perfectly sure of what the errors are telling me now that I have tried all these different ways of implementing the function. I'm all jumbled up and would love some help!
It should be (*rootPtr)->entryPtr, not *rootPtr->entryPtr or rootPtr->entryPtr.
Due to operator precedence, *rootPtr->entryPtr is indeed *(rootPtr->entryPtr).
Related
I'm working with linked lists and I have the following struct:
typedef struct s_list
{
void *content;
struct s_list *next;
} t_list;
I was trying to make a function that swapped first 2 elements and tried this:
void sa(t_list **a)
{
if (!*a && !*a->next)
return ;
}
And it gave me the following two errors:
member reference base type 't_list *' (aka 'struct s_list *') is not a structure or union gcc
expression must have pointer-to-struct-or-union type but it has type "t_list **" C/C++(132)
However if I do this:
void sa(t_list **a)
{
t_list *t;
t = *a;
if (!*a && !t->next)
return ;
}
It works. Why is this? What am I missing?
Operator precedence. -> has higher operator precedence than unary *. Hence "expression must have pointer-to-struct-or-union type but it has type "t_list **", because the compiler tries to apply ->next on a t_list** type.
Fix: (*a)->next.
I'm facing two errors when trying to assign a value to the components of a struct and later when passing a pointer of struct to a function.
I have a user-defined data type: my_node defined in a header file as follows:
enum n_type
{
N_COMMAND,
N_PIPE,
N_REDIRECT,
N_SUBSHELL,
N_SEQUENCE,
N_DETACH
};
struct my_node;
typedef struct my_node node_t;
struct my_node
{
enum n_type type;
union {
struct {
char *program;
char **argv;
size_t argc;
} command;
struct {
node_t **parts; // array
size_t n_parts;
} pipe;
struct {
... etc
}
and I have a function that takes a pointer to a my_node variable:
void run_command(struct my_node *a_node);
In myprogram.c, I try to make a new node, populate its components, define a pointer to its address then pass the pointer to the function above like this:
// first I get input as a string:
fgets(str, 100, stdin);
// create the new node
struct my_node
{
enum n_type type;
union
{
struct {
char *program;
char **argv;
size_t argc;
} command;
};
} node;
// assign values to its components (values are just for testing)
node.type = N_COMMAND;
node.command.program = &str;
node.command.argv = &node.command.program;
node.command.argc = 3;
// define a pointer to the node
struct my_node *ptr;
ptr = &node;
//pass the pointer to run command to execute it
run_command(ptr);
When I try to compile, I get those weird errors:
gcc ./shell.c -o shelli
./shell.c: In function ‘main’:
./shell.c:37:23: warning: assignment from incompatible pointer type [-Wincompatible-pointer-types]
node.command.program = &str;
^
./shell.c:47:14: warning: **passing argument 1 of ‘run_command’ from incompatible pointer type** [-Wincompatible-pointer-types]
run_command(ptr);
^~~
In file included from ./shell.c:2:0:
./shell.h:21:6: note: **expected ‘struct tree_node *’ but argument is of type ‘struct tree_node *’**
void run_command(struct tree_node *n);
^~~~~~~~~~~
How come that the provided and requested argument types are the same but still there's an error?
What is the type of str? My guess is that it's a char* since you used it as a parameter to fgets, and the compiler didn't complain. If that is the case, then
node.command.program = &str;
doesn't compile since node.comand.program has type char*, but the type of &str is char**. So, the solution is to remove the &, ie.
node.command.program = str;
The compile messages indicate a struct tree_node type, but that type isn't defined in your question. I'll assume it is similar to your struct node definition. With this assumption, the run_command(ptr) is a problem since you redefined what a struct node is in your source file. The redefinition is not compatible with the original definition in the header file. You should define a struct only once in a header file, and then include that header file in any source file that uses that struct.
I'm new to this header files in C.
What I'm trying to do is using makefile to compile my code files together. I have 2 header files and 2 c files for each header, also 1 main.c file.
I have main.c which is my main function and it has "#include "dict2.h"". dict1 and dict2 headers are somewhat the same. the difference is dict2 has additional linked list function.
-bash-4.1$ make dict1
gcc -Wall -c main.c -o main.o -g
In file included from main.c:6:
dict2.h:1: warning: useless storage class specifier in empty declaration
dict2.h:8: warning: useless storage class specifier in empty declaration
dict2.h:21: error: expected declaration specifiers or '...' before 'record_t'
dict2.h:24: error: expected declaration specifiers or '...' before 'record_t'
dict2.h:42: error: expected '=', ',', ';', 'asm' or '__attribute__' before '*' token
dict2.h:45: error: expected '=', ',', ';', 'asm' or '__attribute__' before '*' token
dict2.h:48: error: expected ')' before '*' token
make: *** [main.o] Error 1
my dict2.h funtion is looking like this:
typedef struct record_t;
typedef struct node_list node_list_t;
struct node_list;
typedef struct list_t;
typedef struct node node_t;
struct node;
node_t* transform_input(FILE *finput, node_t *root);
//line 21
node_t* bst_insert(node_t *root, record_t* data);
//line 24
node_t* bst_create_node(node_t* root, record_t* data);
node_t* bst_search(node_t* root, char* name_keyword, int* numcomparison);
void search_then_print(char* keyword, node_t* root, FILE* foutput, \
int* numcomparison);
void freeTree(node_t *root);
void print_record(FILE* foutput, node_t* targetnode, char* keyword,\
int* numcomparison);
//line 42
list_t *insert_at_foot(list_t *list, record_t *datarecord);
//line 45
list_t *create_empty_list(void);
//line 48
void free_list(list_t* list);
I've looked at the discussion online but and trying to fix it but I couldn't find the errors in the header file.
Thank you for your help.
Statements:
typedef struct record_t;
typedef struct list_t;
miss the typenames.
Should probably be:
typedef struct record record_t;
typedef struct list list_t;
In the following, I use struct tag vs. type identifier. I googled a bit and found a (IMHO) quite easy to understand explanation on Wikipedia.
Some programmer dude mentioned this but it seems you didn't understand his point. So, I elaborate this a little bit:
This is valid:
struct Node {
struct Node *pNext;
};
and can be used with struct:
void insert_after(struct Node *pNode);
For whom which are to lazy to type the struct always a typedef can help:
struct Node {
struct Node *pNext;
};
typedef struct Node Node;
It might look confusing but the compiler separates struct tags and types in separate lists. Thus, the first and second Node is no identifier "collision".
Both can be done in at once:
typedef struct Node {
struct Node *pNext;
} Node;
Assuming another case without "recursive" usage of type, the struct tag can even be left out:
typedef struct {
int year, month, day;
} Date;
This is a struct type which can be used exclusively without struct keyword.
I assume this was intended when writing
typedef struct record_t;
but the compiler interpretes it not as the writer might intend it. The compiler reads this as struct with tag record_t and a missing type identifier.
This is how I read the
warning: useless storage class specifier in empty declaration
(It helps to know that typedef is syntactically handled in the compiler like static and extern and, thus, counted as storage class though this seems not quite obviously to everybody.)
I must admit that I don't know how to interprete the
error: expected declaration specifiers or '...' before 'record_t'
but I would ignore this and just fix the weakness in the typedef (and count the error as follow-up error.)
I also must admit that I have no idea how to solve this with an anonymous struct and go with the idea of a struct with a tag which is "re-used" as type identifier:
#include <stdio.h>
/* typedef for an incomplete struct */
typedef struct Date Date;
/* use incomplete struct type for prototype of function */
void printDate(Date *pDate);
/* define the complete struct */
typedef struct Date {
int year, month, day;
} Date;
/* implementation of function */
void printDate(Date *pDate)
{
printf("%04d/%02d/%02d", pDate->year, pDate->month, pDate->day);
}
/* check this out */
int main(void)
{
Date date = { 2018, 9, 3 };
printDate(&date);
return 0;
}
Output:
2018/09/03
Live Demo on ideone
I made a program to update some type structure but on compiling two errors occurred, my program is as follows:
#include <stdio.h>
struct a {
char *name;
int id;
char *department;
int num;
};
typedef struct a ab;
void swap(ab *,ab *);
ab * update(ab *);
int main(int argc,char *argv[])
{
ab array[2]={{"Saud",137,"Electronics",500},{"Ebad",111,"Telecom",570}};
ab *q;
*q=update(&array[0]);
}
ab * update(ab *p)
{
p->name="Talha";
p->id=234;
p->department="Civil";
p->num=567;
return *p;
}
On compiling, two errors appeared in assigning and returning to pointer. Kindly notify my mistake, and make a correction to it. The errors are,
newproject.c: In function ‘main’:
newproject.c:29:4: error: incompatible types when assigning to type ‘ab {aka
struct a}’ from type ‘ab * {aka struct a *}’
*q=update(&array[0]);
^
newproject.c: In function ‘update’:
newproject.c:56:9: error: incompatible types when returning type ‘ab {aka
struct a}’ but ‘ab * {aka struct a *}’ was expected
return *p;
^
Remove the * in return *p;. You want to return a pointer address, not the pointed-at data. This is the reason for the compiler error.
Please note that ab *q; *q=update(&array[0]); also does not work because q does not point at valid data. This code is going to cause a program crash or similar.
See this: Mysterious crash or “segmentation fault” when data is copied/scanned to an uninitialized pointer.
bag-implementation.h:
typedef struct node {
struct node *next;
char *element;
int repeats;
} Node;
typedef struct{
size_t size;
Node *head;
}Bag;
Line that errors in bag.c (which includes bag.h which includes bag-implementation.h):
Bag bag_union(Bag bag1, Bag bag2){
Bag union;
return bag1;
}
Error:
bag.c: In function 'bag_union':
bag.c:188:12: error: expected '{' before ';' token
bag.c:188:7: error: two or more data types in declaration specifiers
make: *** [bag.o] Error 1
If I try to compile without creating that bag, then it works fine. What is the issue?
union is a reserved word in C, so you can't have a variable called like this. Simply rename it.
union is a keyword it can't be used for variable.
This is the rule to define a variable.