-3

I've been tampering with linked lists that is storing values of type char array. The issue I'm having is retrieving the value to be stored in another char that will be used for display.

I've tried using (example):

char display*;
node * data = <method to retrieve data as node *>

strcpy(display, data->value); 

This gives me warning: "passing argument 2 of ‘strcpy’ makes pointer from integer without a cast" pointing to data.

sprintf(display, "%s", data->value);

This gives me warning:

"format ‘%s’ expects argument of type ‘char *’, but argument 3 has type ‘int’"

pointing to data->value and suggesting I used %d instead.

At the moment if I compile the first letter is showing but the rest are tiny squares/characters.

What am I doing wrong?

Thanks

[Edit]

This is the initialisation of the struct:

typedef struct node_list {
    char value;
    struct node_list * next;
} node;

This is push:

void push(char *value) {
    node_list* n = (node*)malloc(sizeof(node));

    n->value = *value;
    n->next = head;
    head = n;
}

[Edit 2]

Fixed Sorry for the waste of time. Guide I was following has apparently mistakes in it as it declared the struct with char value instead of char value[10] (for example.)

Badrukk
  • 3
  • 3
  • Is it correct what you say, that the list is "storing values of type char"? Not values of type `char *` (i.e. strings)? – Paul Ogilvie Jan 07 '20 at 15:19
  • 3
    What is the definition of `node`? – Scott Hunter Jan 07 '20 at 15:19
  • what is the type of data->value? If it's a char it's normal, it should be a char* – Kulbuto Jan 07 '20 at 15:20
  • When adding values i'm calling a method which is pushing as: node->value = *value; – Badrukk Jan 07 '20 at 15:21
  • The typedef struct is called node. – Badrukk Jan 07 '20 at 15:22
  • 2
    You can try `sprintf(display, "%c", data->value);`. Your value is of type int or char, but strcpy and "%s" need a pointer to char. – Holger Jan 07 '20 at 15:27
  • Only shows first letter with %c. – Badrukk Jan 07 '20 at 15:35
  • @Badrukk: a `char` only holds one letter. IDK how this doesn't just crash when you pass a `char` value as a `char*` to `strcpy` or `sprintf`; small integers aren't valid pointers in most implementation. And even `&value` wouldn't be a 0-terminated C string. – Peter Cordes Jan 07 '20 at 15:36
  • Apologies my bad. The guide I was following must have been bad. When declaring the struct it didn't declare it as an array. I fixed it. Sorry for the confusion. – Badrukk Jan 07 '20 at 15:45
  • `char value[10]` is significantly different from `char *value`. An array is storage right in the struct, a `char*` only holds a pointer to storage elsewhere (e.g. malloc). – Peter Cordes Jan 07 '20 at 15:54
  • The guide I was following declared it as a regular char not even a pointer. That was the main problem. Sorry for the waste of time. – Badrukk Jan 07 '20 at 15:55

3 Answers3

1

You are passing your push function a string, but only storing the first character of it in your list node. If you want to store the whole string, you're going to need to make a few changes.

Firstly, you need to change value to be a char * in your structure.

typedef struct node_list {
    char *value;
    struct node_list * next;
} node;

and in your push function you need to make a copy of the string to store it in the node.

n->value=malloc(strlen(value)+1); // allocate memory to store the new string plus 1 extra for the null terminator
strcpy(n->value, value); // copy the string

you will need to remember to free that extra memory when you come to destroy the list later.

This still won't completely fix the code you originally posted as display is an uninitialised pointer so you can't just strcpy or sprintf to it. You'd either need to allocate enough memory for it like I've done above in push or you could just assign the value to display since judging by the name, you're only going to display it.

Or maybe not even bother with display at all and just use the value from the node as is. The following will work just fine...

node * data = <method to retrieve data as node *>
printf("Node value is %s\n",data->value);
Chris Turner
  • 8,082
  • 1
  • 14
  • 18
  • Some C implementations provide a `strdup` which does the malloc(strlen) + copy. I might have used `memcpy` after we already have the length from `strlen`, instead of forcing `strcpy` to also search for the terminating `0`. But yes, your example gets the important point across clearly, probably more clearly than anything fancier. – Peter Cordes Jan 07 '20 at 15:49
  • Yes, I could have included `strdup`, but as you've pointed out, only some C implementations provide it. – Chris Turner Jan 07 '20 at 15:50
  • The guide I was following wasn't fully functional then. Thank you for the explanation and showcase. – Badrukk Jan 07 '20 at 15:51
0

It's occur because the member "value" of struct "node" probably is an int (integer) type.

Post all your code for more details.

cayo
  • 17
  • 4
-2

The convertion char "%s" expect a pointer of char (*char) and the member "value" of your struct is of char type (all char type can converts to int type because all char is represented by int value, exactly i said before).

Furthermore, the strcpy function is not work with char type. The prototype of strcpy function is: char * strcpy ( char * destination, const char * source );

In your member "value", you need to save only char or char array?

If you need a char array, and you needs change your struct to:

typedef struct node node_list;
struct node {
    char *value;
    node_list *next;
};

and you have allocate memory for "value" member after allocate memory to your node pointer and the use strcpy function, like this:

void push(char **value) {
    node_list* n = (node_list*)malloc(sizeof(node_list));
    n->value = (char *) malloc(sizeof(char));

    strcpy(n->value, *value);
    printf("Output: %s\n", n->value);

    free(n->value);
    free(n);
}

Main program example:

int main(int argc, char **argv)
{
    char *palavra = (char *) malloc(sizeof(char));

    printf("Input: ");
    scanf("%[^\n]s", palavra);

    push(&palavra);

    free(palavra);

    return (0);
}
cayo
  • 17
  • 4