Adding Characters into Struct - c

I am trying to read characters into a linked list (I made this simple test code just to try to read in the characters) for some reason I cannot get it to read in a character value.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
struct node
{
char name[50];
struct node *next;
}*head;
void add(char AddName);
int main()
{
head = NULL;
char TempName[50];
printf("What Name");
scanf(" %s", TempName);
add(TempName);
printf("%s",head->name);
return 0;
}
void add(char AddName)
{
struct node *temp;
temp = (struct node*)malloc(sizeof(struct node));
strcpy(temp->name,AddName);
head = temp;
head->next = NULL;
}
I understand this is not how a linked list works I just made this to try to get to be able to run a single character name into the struct and print it back out. (I should be able to enter in the name Bob and it prints bob)

I think your function parameter definition is wrong. Try this:
void add(char *AddName)
{
....
}

Related

Ask data from user and store them inside a struct in C

In the code below I tried to use printf and scanf to get data from user and store them inside a struct i defined called node.
The programme works fine for the first prompt, but as soon as the user input name, the programme ends with printing Age:salary:
Can anyone help me with this?
On a side note, can anyone also help me to understand how to create a loop to store data in various nodes and store them together? (Not hard-code it one by one)
Thank you very much!!
typedef struct node
{
char *name;
int age;
int salary;
struct node * next;
}node;
int main(void)
{
node *tmp = malloc(sizeof(node));
printf("Name:");
scanf("%s", tmp->name);
printf("Age:");
scanf("%i", &(tmp->age));
printf("salary:");
scanf("%i", &(tmp->salary));
tmp->next = NULL;
free(tmp);
}
Use a char[] for name,
for example:
#include <stdlib.h>
#include <stdio.h>
typedef struct node
{
char name[128];
int age;
int salary;
struct node * next;
}node;
int main(void)
{
node *tmp = malloc(sizeof(node));
printf("Name:");
scanf("%s", tmp->name);
printf("Age:");
scanf("%i", &(tmp->age));
printf("salary:");
scanf("%i", &(tmp->salary));
tmp->next = NULL;
free(tmp);
}
If you want to get several users, loop for ever and ask if the user wants to add more data.
I have create a function to print the list
Console:
Name:Foo
Age:12
salary:12
Continue Y/N
Y
Name:Bar
Age:14
salary:14
Continue Y/N
Y
Name:John
Age:30
salary:45
Continue Y/N
N
John, 30, 45
Bar, 14, 14
Foo, 12, 12
#include <stdlib.h>
#include <stdio.h>
typedef struct node
{
char name[128];
int age;
int salary;
struct node * next;
}node;
static void printList(node *n)
{
while (n) {
printf("%s, %d, %d\n", n->name, n->age, n->salary);
n = n->next;
}
}
static node *get_nodes(void) {
node *list = NULL;
while (42) {
char c;
node *tmp = malloc(sizeof(node));
printf("Name:");
scanf("%s", tmp->name);
printf("Age:");
scanf("%i", &(tmp->age));
printf("salary:");
scanf("%i", &(tmp->salary));
tmp->next = list;
list = tmp;
printf("Continue Y/N\n");
scanf(" %c", &c);
if (c == 'N')
break;
}
return list;
}
static void clearList(node *node) {
if (node->next) {
clearList(node->next);
}
free(node);
}
int main(void)
{
node *list = get_nodes();
printList(list);
clearList(list);
return 0;
}
You are trying to write to Uninitialized memory
This is a very common problem beginners face.
You are trying to store the name using char *name declaration.
Here name does not point to a valid memory location, that's why You program is not running as expected.
Even if name points to a valid memory address, you must have enough memory allocated to store the data.
You can use
#define BUFFER_SIZE 50
char name[BUFFER_SIZE];
You can use any buffer size as you like, and then store a string of that length - 1 in the name array. -1 is for the null termination character \0.
Using this declaration you are allocating memory of BUFFER_SIZE bytes and the name points to the first byte in that array.
This allocation happens on the stack not in the HEAP
For fix your bug, you should allocate memory of your char *.
First Way, when you create your struct.
typedef struct node
{
char name[200]; // You specify that your char * can save 200 char
int age;
int salary;
struct node * next;
}node;
or you can create init struct function
node *init_node()
{
node *test = null;
test->name = malloc(sizeof(char) * 200);
test->age = 0;
test->salary = 0;
test->node = null;
return test
}

Structure with pointer for string

I have a char pointer in the structure to store names.When I inserted the values and printed the last value of name is getting printed for all nodes.
typedef struct tests{
int id;
char *p;
struct tests *next;
}test;'
'void add(test **root,int id,char *name){
test *newnode=(test* )malloc(sizeof(test));
newnode->id=id;
newnode->p=name;
newnode->next=NULL;
test *curr;
curr=(*root);
if((*root)==NULL){
(*root)=newnode;
}
else{
while(curr->next!=NULL){
curr=curr->next;
}
curr->next=newnode;
}
}
Most likely what you intend to achieve is something along these lines:
#include <stddef.h>
#include <stdlib.h>
#include <string.h>
typedef struct test_s {
int id;
char *p;
struct test_s *next;
} test_t;
test_t** add(test_t **root, int id, char const *name){
size_t len = strlen(name);
test_t *newnode=(test_t*)malloc(sizeof(test_t)+len+1); // 1 goes for \0 terminator
newnode->id=id;
strcpy(newnode->p=(void*)(newnode+1), name);
newnode->next=NULL;
test_t **tail = root;
while (*tail) {
tail = &(*tail)->next;
}
*tail = newnode;
return &(newnode->next);
}
Problem with your code is, you never copied your string assigning just a single pointer instead.
Take a look at pointers mechanics once again, additionally I would advise you to check string.h reference.

How do linked list work if nothing has been added to them and you try to print that variable

I have a linked list and want to print it out in the end. My questions is, if the linked list variable in the struct is left untouched and nothing is added to the list, if I try to print using while(school->list!= NULL) will this work?
Note: I have no made the list NULL at any point, I have just allocated name and not touched the list.
struct School{
char *name;
Student *list; <--- Linked list
} School;
struct Student{
char *name;
Student *next;
} Student;
Now if I want to print this list will this work?
Edit: I changed (school->student != NULL) to (school->list != NULL)
Well see this example to print a list:
#include <stdio.h>
#include <stdlib.h>
struct test{
int code;
struct test *next;
};
void pri(struct test *); // As you dont whant to change the values of list.
void cre(struct test **);// This put list at the start
int main(void){
struct test *head;
head = NULL; // you start from null.
cre(&head,5);
cre(&head,10);
pri(head);
return 0;
}
void cre(struct test **head,int x){
struct test *tmp;
tmp = malloc(sizeof(struct test));
tmp->code = x;
tmp->next = (*head);
(*head) = tmp;
}
void pri(struct test *head){
while(head){ // while we dont reach end of list.
printf("%d ",head->code);
head = head->next; // Go to our next element
}
printf("\n");
}
I hope this program help you to print lists.This works of course if we insert an element to our list at the end etc.Make a draw to your paper to understand lists better.

Transfer char arrays into linked list

I have been hesitant to post a question about this because I'm worried about asking a stupid question, but here it goes:
I am currently trying to create a program that will take whole strings, put them into char arrays and transfer those char arrays to a linked list. I have everything working up to the point of actually putting the arrays into the linked list.
I initially tried to just create each node with the array itself, which was just giving me the first element of the array. Then I found that I need to use strcpy().
I'm not sure what is wrong at this point, but I think it's down to memory allocation because it's giving me a segfault. That is confusing however, because the memory allocation for rach node is already taken care of.
Thank you for any help, this part has been driving me crazy for a few hours now.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define SIZE 100
struct node {
char info;
struct node *link;
} *start;
void create(char[]);
void display();
void insert_end(char[]);
int main() {
int i;
start=NULL;
char data[SIZE];
printf("Please enter a word: ");
fgets(data, SIZE, stdin);
create(data);
for(i=0; i<5; i++)
{
printf("Please enter a word: ");
fgets(data, SIZE, stdin);
insert_end(data);
}
display();
return 0;
}
void create(char data[])
{
struct node *temp;
temp = (struct node *)malloc(sizeof(struct node));
if (start == NULL)
{
strcpy(temp->info,data);
temp->link=NULL;
start=temp;
}
}
void display()
{
struct node *ptr;
ptr = start;
while (ptr!=NULL)
{
printf("%c", ptr->info);
ptr=ptr->link;
}
}
void insert_end(char data[])
{
struct node *ptr, *tempnode;
ptr = start;
while(1)
{
if(ptr->link != NULL)
{
ptr=ptr->link;
}
else
break;
}
tempnode=(struct node *)malloc(sizeof(struct node));
strcpy(tempnode->info,data);
tempnode->link=NULL;
ptr->link=tempnode;
}
As you stated you are using arrays, space needs to be reserved in the info member of the linked list structure. char type will only hold one character.
struct node {
char info[SIZE];
struct node *link;
} *start;
If info is an array, printf requires %s format modifier.
printf("%s\n", ptr->info);
info is a char not a char *.
Compile with -W -Wall, you'll see most of your mistakes.

Why aren't the elements of my Doubly Linked List displayed properly?

The following program receives input strings of the form ins "name_to_insert" birthdate and should insert this information in a doubly linked list. The contents of the list are displayed after each insertion, along with the number of elements. The number of elements is being displayed correctly, but instead of the names and birth dates, 2686707 is being displayed n times (n=number of elements in the list).
I suspect something is wrong with my print function, printList(), but I couldn't figure out what.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "DLList.h"
typedef struct dataStructure
{
int birthday;
char *name;
} dataStructure;
int main()
{
ListT *l=createList();
char op[4], nameTemp[30], *name, s[50];
int date;
while (scanf("%[^\n]%*c", s)==1)
{
sscanf(s, "%s", op);
if (strcmp(op, "ins")==0)
{
sscanf(s, "%*s %[^0-9]%d", nameTemp, &date);
name=nameTemp+1; // Remove opening quotation mark
name[strlen(name)-2]='\0'; // Remove closing quotation mark
NodeT *p=createNode();
p->data=(dataStructure*)malloc(sizeof(dataStructure));
((dataStructure*)p->data)->birthday=date;
((dataStructure*)p->data)->name=name;
insertLastNode(l, p);
printf("List length: %d\n", l->length);
printList(l);
}
}
return 0;
}
void printList(ListT *l)
{
NodeT *p=l->first;
while (p)
{
printf("%d %s\n", (((dataStructure*)p->data)->birthday, (dataStructure*)p->data)->name);
p=p->next;
}
printf("--\n");
}
Contents of DLList.h:
#include <stdio.h>
#include <stdlib.h>
typedef struct nodetype
{
struct nodetype *prev, *next;
void *data;
} NodeT;
typedef struct
{
int length;
NodeT *first, *last;
} ListT;
NodeT *createNode();
ListT *createList();
void insertLastNode(ListT *l, NodeT *p);
Contents of DLList.c:
#include "DLList.h"
NodeT *createNode()
{
NodeT *p=(NodeT*)malloc(sizeof(NodeT));
p->next=p->prev=NULL;
return p;
}
ListT *createList()
{
ListT *l=(ListT*)malloc(sizeof(ListT));
l->first=l->last=NULL;
l->length=0;
return l;
}
void insertLastNode(ListT *l, NodeT *p)
{
if (l->first==NULL)
{
l->first=l->last=p;
p->prev=p->next=NULL;
l->length++;
}
else
{
p->prev=l->last;
p->next=NULL;
l->last->next=p;
l->last=p;
l->length++;
}
}
Two errors in the code.
First:
Instead of
((dataStructure*)p->data)->name=name;
do
((dataStructure*)p->data)->name = (char*)malloc(strlen(name)+1);
strcpy(((dataStructure*)p->data)->name, name);
to avoid memory leakage.
Second
In printList function there was a mistake with parentheses. Do as below:
printf("%d %s\n", ((dataStructure*)p->data)->birthday, ((dataStructure*)p->data)->name);
Everything else works. Here is output I got when tested the program.
In your program, you are assigning the pointer to name as below:
((dataStructure*)p->data)->name=name;
This name is derived from the sscanf as below:
sscanf(s, "%*s %[^0-9]%d", nameTemp, &date);
name=nameTemp+1; // Remove opening quotation mark
name[strlen(name)-2]='\0'; // Remove closing quotation mark
This means that for every run of the loop, you are reading into the same nameTemp or name array and storing the same into the linked list. For every run of the loop, you may have to allocate a separate space for storing the name and assign the same to your node.
EDIT 1:
When you create a new node, there is also one type-casting issue. p->data is of void * type, in the code, I believe, the newly allocated memory is type-casted as dataStructure * as below
p->data=(dataStructure*)malloc(sizeof(dataStructure));
You could also change your data structure definition as below
typedef struct dataStructure
{
int birthday;
char name[64]; // Change from pointer to an array
} dataStructure;
And modify the logic in the loop to copy the name as below:
p->data=(dataStructure*)malloc(sizeof(dataStructure));
((dataStructure*)p->data)->birthday=date;
strcpy(((dataStructure*)p->data)->name, name); // Modified from pointer assignment to strcpy
Run this in a debugger to see exactly what your function is doing. For example if you're running from a Unix command line, compile with the -g flag, then run in gdb. Set a breakpoint at the beginning of the function that is troubling you. Google something like "gdb cheat sheet" for details, it's easy.

Resources