Basically I have to store words in linked list with each character having its own node. I get really confused with nested structures. How do I go to the next node? I know i'm doing this completely wrong which is why I'm asking.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef struct node
{
char letter;
}NODE;
typedef struct handle
{
NODE **arr;
}HANDLE;
HANDLE * create();
void insert(handle **, char, int);
int main(int argc, char **argv)
{
FILE *myFile;
HANDLE *table = (HANDLE *)malloc(sizeof(HANDLE));
NODE *linked = (NODE *)malloc(sizeof(NODE));
int counter = 0;
linked = NULL;
table->arr[0] = linked;
char c;
myFile = fopen(argv[argc], "r");
while((c = fgetc(myFile)) != EOF)
{
if(c != '\n')
insert(&table, c, counter);
else
{
counter++;
continue;
}
}
}
void insert(HANDLE **table, char c, int x)
{
(*table)->arr[x]->letter = c; //confused on what to do after this or if this
//is even correct...
}
You have a linked list of words with each word being a linked list of characters. Am I right? If so, it is better to use the names for what they are:
typedef struct char_list
{
char letter;
struct char_list * next;
} word_t;
typedef struct word_list
{
word_t * word;
struct word_list_t * next;
} word_list_t;
Now, you can populate the lists as per need.
For a linked-list, you typically have a link to the next node in the node structure itself.
typedef struct node
{
char letter;
struct node *next;
}NODE;
Then from any given node NODE *n, the next node is n->next (if not NULL).
insert should scan the list until it finds an n->next that is NULL, and allocate a new node at the end (make sure to set its next to NULL).
You may want to have a function to initialize a new list given the table index, and a separate function to initialize a new node.
Related
I am trying to read a binary file which it has names,years, from movies and then to create a list from that file data....but when am using this code am getting a blank screen.
struct node *next;
}node;
node *head;
node *tail;
node*inventory = NULL;
int main(int argc , char * argv){
node *current;
node n;
node *p;
FILE *ptr;
ptr=fopen("movies.dat", "rb");
head= NULL;
while(!feof(ptr))
{
p = (node*)malloc(sizeof(node));
if (!head)
{
head =(node*) malloc(sizeof(node));
current = head;
}
fread(p, sizeof(node), 1, ptr);
current->next = p;
p=current;
}
fclose(ptr);
The example output should look like this:
$ ./a.out --list-all
The Godfather 1972 245066416.00
Snatch 2000 30093108.00
Thanks in regards
First of all a list should look like this
Inside the header file :
typedef struct Node_t Node;
struct Node_t
{
void* data;
int id;
Node_t* next_node; //next node
};
typedef struct List_t
{
int number_of_nodes;
Node_t* start_index; //pointer , points at first node , start of the list.
}List;
So upon reading (which seems ok) , for each movie you have to create a structure to hold movie data.Let's say
typedef struct Movie_t
{
char name[16];
int year;
}Movie_t;
So in every element you read you store name and year in a struct and then you create a Node_t that points for void* data in the pointer of the Movie_t object and you add Node_t in list.
Your code is not enough to help you where exactly you made the mistake. Hence I have developed the below codes for you. Just modify the structure for more field and change the code accordingly so that you can learn properly.
struct Movie
{
char *name;
char *date;
struct Movie *next;
};
struct Movie * initialize(char *);
void display(struct Movie *);
int main()
{
struct Movie *head;
char fname[100];
head=initialize("movies.dat");
display(head);
}
struct Movie * initialize(char *fname)
{
FILE* fpointer;
char ch;
fpointer = fopen(fname,"r");
if(fpointer == NULL)
{
printf("\nFile not found");
exit(1);
}
//FILE IS OPENED
struct Movie *head=NULL;
struct Movie *t;
char line[255];
char sent[2]=";";
while(!feof(fpointer) && fgets(line,sizeof line,fpointer))
{
char *name=strtok(line,sent);
char *date=strtok(NULL,sent);
if(head == NULL)
{
head=(struct Movie*)malloc(sizeof(struct Movie));
t = head;
t->name = (char *)malloc(strlen(name));
t->date = (char *)malloc(strlen(date));
strcpy(t->name,name);
strcpy(t->date,date);
t->next=NULL;
}
else
{
t->next=(struct Movie*)malloc(sizeof(struct Movie));
t=t->next;
t->name = (char *)malloc(strlen(name));
t->date = (char *)malloc(strlen(date));
strcpy(t->name,name);
strcpy(t->date,date);
t->next=NULL;
}
}
return head;
}
void display(struct Movie *h)
{
while(h!=NULL)
{
printf("Name :%20s %10s\n",h->name,h->date);
h=h->next;
}
}
now create movies.dat with below information:-
The Godfather;1972;
Snatch;2000;
here in the file you can add as many as film information. Here every field has been separated by ; you can separate field with any special character as per your wish but you need to make necessary changes in the below line of code each time.
char sent[2]=";";
Your field separator can be any character for example The Godfather|1972| in this case you need to modify your code like char sent[2]="|"; Better give it a proper name like char seperator[2]=":"; here your separator is :
Also do not forget to add header files , and
Wish you all the very best.
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.
I have a struct and in that a struct i have a character pointer but and i am creating different instances of this struct but when i am changing the pointer in one struct the other is also changing.
#include <stdio.h>
#include <stdlib.h>
typedef struct human{
int age;
char name[100];
} Human;
int main(){
FILE *s = fopen("h.txt","r");
if(s==NULL){
printf("file not available");
}
for(int i=0 ;i<5;i++){
Human h;
fscanf(s,"%d",&h.age);
fscanf(s,"%s",h.name);
insertintolinkedlist(h);
// this method is going to insert the human into the linked list
}
return 0;
}
what is happening that all humans in the linked list have different ages but same name!
You need to allocate memory to hold the name.
char* name is just a pointer - it has no memory for saving the name.
You change it to
char name[100];
Remember to check that the names you put into Human.name isn't longer than 100 characters.
To use a linked list you can do something like:
typedef struct human{
int age;
char name[100];
struct human* next;
} Human;
int main()
{
Human* head = NULL;
Human* tail = NULL;
for(.....)
{
Human* h = malloc(sizeof(Human));
if (head == NULL) head = h;
if (tail != NULL)
{
tail->next = h;
}
tail = h;
h->next = NULL;
h->age = ....;
strncpy(h->age, "..name..", 100);
}
// ..... other code
// Remember to free all allocated memory
}
Everywhere I look about Linked List implementation, I see that when I initialize a list my code should look something like this:
typedef struct node {
int val;
struct node * next;
} node_t;
But my assignment says this for my initialize function: Write a function initializeList which creates a linked list of employee information where each node contains an employeeData struct and a pointer called next.
What I got from that is to do this, but I dont think its right:
#include <stdio.h>
#include <stdlib.h>
#include <strings.h>
FILE * data;
typedef struct{ // Main struct containing needed data types
int EMP_ID;
int dep;
int rank;
double salary;
char name[20];
} node;
struct node { node employeeData; struct node *next; }; // struct node
struct node *head, *z, *t;
initializeList ( node employeeData, FILE *data ) // initialize list function
{
head = ( node * ) malloc( sizeof *head );
z = ( node * ) malloc( sizeof *z );
head->next = z;
z->next = z;
}
int main (void)
{
data = fopen( "empInfo.txt","r" );
node employeeData = {0,0,0,0,0};
while (getchar () != '\n')
getchar ();
fclose( data );
return 0;
}
Is this a correct implementation of this? Very new to programming so please be easy on me. My assignment is no where near done so I am aware that it doesn't really do anything right now.
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "dictionary.h"
#define HASH_SIZE 100
// prototype
int hash(char *word);
// counter
int counter;
// node
typedef struct
{
char *word;
node *next;
} node;
// hash table
node *hashtable[HASH_SIZE];
bool
load(const char *dictionary)
{
// open the dictionary
FILE *dict = fopen(dictionary, "r");
if(dict == NULL)
{
printf("Could not open %s.\n", dictionary);
return false;
}
// set all values in the hash table to null
for(int i = 0; i < HASH_SIZE; i++)
{
hashtable[i] = NULL;
}
// set the counter to 0
counter = 0;
// iterate through the words in the dictionary
while (!feof(dict))
{
// get word into a string
char gotcha[LENGTH];
fscanf(dict, "%s", gotcha);
// declare a node and allocate memory
node n;
n.word = malloc( strlen(gotcha)*sizeof(char) );
// save the word into the node
strcpy(n.word, gotcha);
// hash the word, baby!
int hash_value = hash(n.word);
// start saving addresses to the hashtable
n.next = hashtable[hash_value];
hashtable[hash_value] = &n;
//test
int len = strlen(n.word);
printf("%s\n", n.word);
printf("%i\n", len);
// that's one more!
counter++;
}
fclose(dict);
return true;
}
I am receiving the following two errors on these two lines of code:
n.next = hashtable[hash_value];
hashtable[hash_value] = &n;
dictionary.c:89:16: error: assignment from incompatible pointer type [-Werror]
dictionary.c:90:31: error: assignment from incompatible pointer type [-Werror]
How do I save pointer values in these two places? I am new to this, so please bear that in mind. :)
In your structure, the type node is not yet defined. Change it to use the structure tag:
typedef struct node
{
char *word;
struct node *next;
} node;
This:
typedef struct
{
char *word;
node *next;
} node;
is a syntax error. The node *next; occurs before the end of the typedef that creates node as a type. If your compiler for some reason accepted this, it probably thinks there are 2 different types called "node" now, which explains why one of them isn't compaible with the other. You should give up on that typedef silliness (structs generally shouldn't be typedef'ed) and just use
struct node
{
char *word;
struct node *next;
};
Define typedef names of structs before defining the structs. This allows mutually referring structs without concern for order and doesn't require inconsistent definitions, sometimes with the struct keyword and sometimes without it. Note that in C++ you can do away with the typedef line entirely:
typedef struct node node;
struct node
{
char* word;
node* next;
};