C: incompatible types in assignment - c

typedef char Last_t[MAXL];
typedef char Rest_t[MAXR];
typedef struct NodeTag {
Last_t Last;
Rest_t Rest;
struct NodeTag *Link;
} Node;
typedef struct {
Node *Index[26];
Node *L;
} ContactList;
// parameter to take in a char argument to set it to contact.Last
void INS( Node *cn )
Node contactName;
contactName.Last= cn;
// temp->data=num;
//contactName.Rest=restName;
}
//cant figure out how to pass a char argument
int main(void)
{
INS("David");
}

void INS should be passing an argument of type char *, not Node, if you want the code in your main to work.
To assign it to the member Last, you would have to use strcpy or something similar. This is because you can't assign a pointer to an array. More specifically, you can't assign a char * to char[MAXL].
You could try this:
void INS( char * cn ) {
Node contactName;
strncpy (contactName.Last, cn, MAXL);
}
int main(void){
INS("David");
return 0;
}
But, this doesn't handle errors very well. Here's a way of doing it that's more error-safe:
void INS (char * cn){
Node contactName = {
.Last[0] = 0,
.Rest[0] = 0,
.Link = 0
};
if (cn){
strncpy (contactName.Last, cn, MAXL - 1);
contactName.Last[MAXL - 1] = 0;
}
}
int main (void){
INS ("David");
return 0;
}

Related

struct that holds struct, how to dereference

i have couple of linked lists in my larger program which i now want to keep in a struct (t_holder).
typedef struct s_list
{
int val;
struct t_list *next;
} t_list;
typedef struct s_holder
{
t_list *a_starts;
// more lists...
} t_holder;
now i try to figure out how i dereference this in my program.
void try_out(t_holder *list_holder, int num)
{
//assigning something to a_starts
list_holder->a_starts->val = num;
}
int main(int argc, char *argv[])
{
t_holder *list_holder;
int num;
num = 42;
list_holder = NULL;
try_out(list_holder, num);
return (0);
}
in the function "try_out" i simlpy try to assign a value to a_starts->val but my debugger shows me ACCESS_ERROR if i declare it like this
list_holder->a_starts->val = num;
For starters this typedef declarations
typedef struct s_list
{
int val;
struct t_list *next; // <===
} t_list;
is incorrect. It seems you mean
typedef struct s_list
{
int val;
struct s_list *next; // <===
} t_list;
As for your other code then you declared a null pointer
t_holder *list_holder;
//...
list_holder = NULL;
So dereferencing the null pointer results in undefined behavior.
You need to write something like the following
t_holder list_holder = { .a_starts = NULL };
//...
try_out( &list_holder, num);
and then within the function something like
void try_out(t_holder *list_holder, int num)
{
t_list *node = malloc( sizeof( *node ) );
node->val = num;
node->next = list_holder->a_starts;
list_holder->a_starts = node;
}

Void * to char or int in C

I want to get any types of variables in my code, so I did a void * type to accept others. But I can get in char * but not in int values. And I don't understand how I can did it.
Here my code :
void insertion(t_liste *liste, void *newValue) {
t_element *new = malloc(sizeof(void *));
int i;
int *j = &i;
if (liste == NULL || new == NULL) {
exit(EXIT_FAILURE);
}
if (newValue == j || (char *)newValue) {
new->value = newValue;
new->suivant = liste->premier;
liste->premier = new;
liste->taille++;
new->index = liste->taille;
}
}
In my main I did
insertion(maListe, 5);
it didn't work, but if I did this:
insertion(maListe, "test");
It works.
But I want both works !
Here my .h
typedef struct s_element t_element;
typedef struct s_liste t_liste;
struct s_element{
int index;
void *value;
t_element *suivant;
t_element *precedent;
};
struct s_liste{
t_element *premier;
t_element *dernier;
int taille;
};
Any idea ?
OK! In your function
void insertion(t_liste *liste, void *newValue)
you are taking a argument of type void* . In the first case when you send a string(char *) the base address of the string is passed , so address is taken to newValue,but in case when you pass a number,say 5 ,integer is passed to newValue where it expects an address.

String input by linked list

Is there any way to take a string input(as like we take for any integer) by linked list??
For example:This code is showing run time error:
struct node
{
char c;
struct node *link;
};
while(1)
{
val=getch();
if(val!=10)
add(&a[i],val);
else
break;
}
and I want to take any input string like - "asdfghj", of which string length was not known?
Given that you have a LinkedList-class that acts as an interface to the linked list and that it has the function addNode() that adds a node in a correct manner to the list.
I also assume that what you want to know is how to make every char in the inputted string a node in the linked list and that you know how to manage a linked list.
And assuming you're using C++11
int main()
{
LinkedList list;
string input;
cin >> input;
for(auto i: input)
{
list.addNode(i);
}
}
example for C
#include <stdio.h>
#include <stdlib.h>
typedef struct node {
char c;
struct node *link;
} Node;
typedef struct s_ {
Node *top;
Node *curr;
} String;
Node *Node_new(char ch){
Node *p = calloc(1, sizeof *p);
p->c = ch;
return p;
}
String *String_new(void){
String *p = calloc(1, sizeof *p);
return p;
}
void String_drop(String *s){
Node *p = s->top;
while(p){
s->curr = p;
p = p->link;
free(s->curr);
}
//s->top = s->curr = NULL;
free(s);
}
void String_add(String *s, char c){
if(s->top == NULL){
s->curr = s->top = Node_new(c);
} else {
s->curr = s->curr->link = Node_new(c);
}
}
String *get_string(FILE *fp){
String *s = String_new();
int ch;
while(EOF!=(ch=fgetc(fp)) && ch !='\n'){
String_add(s, (char)ch);
}
return s;
}
void put_string(String *s){
Node *p;
for(p = s->top; p ; p = p->link)
putchar(p->c);
putchar('\n');
}
int main(void) {
String *s = get_string(stdin);
put_string(s);
String_drop(s);
return 0;
}
You can think easily. As You just can declare a string variable instead of char. And after that You can take input normally by creating a struct variable. For example:
#include <bits/stdc++.h>
using namespace std;
struct node
{
string s;
struct node *link;
};
int main(){
node ob;
cin>>ob.s;
cout<<ob.s;
}

Passing struct to function and adding elements

I'm new to C. I'm trying to pass a struct list to a function and within that function fill the list. Code is as follows:
#include <stdio.h>
#include <stdlib.h>
struct Abc {
int test;
struct Abc *next;
};
void demo_fill(struct Abc *data);
int main(int argc, char **argv) {
struct Abc *db = NULL;
demo_fill(db);
printf("%d\n",db->test);
return 0;
}
void demo_fill(struct Abc *data) {
int i;
for( i = 0; i < 5; i++ ) {
struct Abc *new;
new = malloc(sizeof(struct Abc));
new->test = i;
new->next = data;
data = new;
}
}
When running this a 'Segmentation fault (core dumped)' error occurs because the struct is still NULL when I try to print the first element. What am I doing wrong?
You're passing the pointer by value. You need to pass a pointer to a pointer if you want the change the value of the caller's pointer:
int main(int argc, char **argv) {
struct Abc *db = NULL;
demo_fill(&db);
printf("%d\n",db->test);
return 0;
}
void demo_fill(struct Abc **data) {
int i;
for( i = 0; i < 5; i++ ) {
struct Abc *new;
new = malloc(sizeof(struct Abc));
new->test = i;
new->next = *data;
*data = new;
}
}
Assigning data to new will have no effect. data is a local copy of the pointer. Pass a double pointer to fix that. Something like this:
void demo_fill(struct Abc** data) {
int i;
for( i = 0; i < 5; i++ ) {
struct Abc *new;
new = malloc(sizeof(struct Abc));
new->test = i;
new->next = *data;
*data = new;
}
}
And of course you will have to pas the pointer to db in main:
demo_fill(&db)
You can pass a pointer to the pointer as the other two answers say, so i just point out an alternative you might also consider: Instead of using a single struct you could use one struct for the list and another for entry-links:
struct link {
int test;
struct link* next;
};
struct list {
struct link* first;
};
void demo_fill(struct list* data);
You can then modify the first entry of the list without thinking about ** syntax.

How to return a struct without using global declaration of struct in C

Hello i am trying to return a struct from a function but i cant find a way to do so without declaring the struct as global. How can this be done? Here is the code (THIS WORKS AS IT IS)
...
void log_in();
struct node
{
char name_log[20];
int passlog;
int user_point;
}tmp;
int main()
{
...
else if(sel=='2')
{
log_in();
if (tmp.passlog==TRUE)
logged_in(tmp.name_log,tmp.user_point); //and here i want to use the retun values
}
void log_in()
{
... //make the changes in the struct
}
...
What i want to achieve is to place the struct node declaration within main but sadly it wont work. So here is what i am trying to do: (THIS DOESN'T WORK)
...
struct node log_in();
int main() {
...
else if(sel=='2') {
struct node //here is where i want to declare
{
char name_log[20];
int passlog;
int user_point;
}tmp;
log_in();
if (tmp.passlog==TRUE)
logged_in(tmp.name_log,tmp.user_point); //and here i want to use the retun values
}
struct node log_in()
{
...
return tmp;
}
...
else if(sel=='2') //or within this block but I don't know how.
{ struct node tmp;
tmp=log_in();
if (tmp.passlog==TRUE)
logged_in(tmp.name_log,tmp.user_point); //and here I want to use the return values
}
and inside the function log_in()
struct node log_in()
{
struct tmp
...
return tmp;
}
use a local variable inside the function and return this variable. Assign it to another variable inside main().
Declare the structure first, then create the variable temp. Like this:
struct node
{
char name_log[20];
int passlog;
int user_point;
};
Then you can create the local variable like
struct node tmp;
Pass a pointer to the struct node to your log_in function and have it return a boolean value so the caller can check whether logging in succeeded or didn't. (Note I'm trying to guess what you want to achieve, and I might be guessing wrong.)
#include <stdio.h>
#include <string.h>
struct node {
char name_log[20];
int passlog;
int user_point;
};
int log_in(char, struct node *);
int log_in(char sel, struct node * tmp) {
int ret = 0;
if (sel == '2') {
ret = 1;
strcpy( tmp->name_log, "Gonzo" );
tmp->passlog = 33;
tmp->user_point = 99;
}
return ret;
}
int main(int argc, char ** argv) {
struct node tmp;
char sel = argv[1][0];
if ( log_in(sel, &tmp) ) {
// tmp initialized
printf( "%s, %d, %d\n", tmp.name_log, tmp.passlog, tmp.user_point );
}
else {
// tmp not initialized
}
}
Call passing 2 on the command line. (If you don't, undefined behaviour.)
If you want to use some struct in 2 different routines - you must declare it outside of both of them since they both have to see how this struct is structured.
BTW - you invoke log_in but do not use its return value.
You can't operate on a type that is unknown. If log_in() doesn't know the definition of struct node, it can't use it directly. The only thing it can do is somehow receive a pointer to a variable of this type and then either treat it as raw data (sequence of bytes) or cast said pointer to a pointer to a known to log_in() type and work with that.
You can also redefine struct node inside of log_in(), which is a way of making log_in() operate on a known type:
void log_in(void*);
void logged_in(char*, int);
int main(void)
{
int sel = '2';
if (sel == '2')
{
struct node
{
char name_log[20];
int passlog;
int user_point;
} tmp;
log_in(&tmp);
if (tmp.passlog)
logged_in(tmp.name_log, tmp.user_point);
}
return 0;
}
void log_in(void* n)
{
struct node
{
char name_log[20];
int passlog;
int user_point;
} *p = n;
p->passlog = 1;
}
void logged_in(char* name, int point)
{
}
If you don't want to pass tmp by a formal reference into log_in(), you must make it available globally. For example like this:
void log_in(void);
void logged_in(char*, int);
void* pTmp;
int main(void)
{
int sel = '2';
if (sel == '2')
{
struct node
{
char name_log[20];
int passlog;
int user_point;
} tmp;
pTmp = &tmp;
log_in();
if (tmp.passlog)
logged_in(tmp.name_log, tmp.user_point);
}
return 0;
}
void log_in(void)
{
struct node
{
char name_log[20];
int passlog;
int user_point;
} *p = pTmp;
p->passlog = 1;
}
void logged_in(char* name, int point)
{
}

Resources