warning: implicit declaration of function TableCreate - c

I have to build a hash table data structure for this project, which I have done it in other files. For some reason when I compile my program and I get error, which is regarding initialization function (TableCreate();) of hash table. When I remove this part of the code from main function and execute, it works fine but then I get segfault when i try to add something to the hash table.
I believe my hash table code has nothing to do with this errors because my hash table code is based upon examples of Hash table code which was provided to us by our professor
I'm using GCC compiler.
Please help me solve this issue.
Error Message
src/sshell.c: In function âmainâ:
src/sshell.c:34: warning: implicit declaration of function âTableCreateâ
src/sshell.c:34: warning: assignment makes pointer from integer without a cast
sshell.c
#include "parser.h"
#include "shell.h"
#include "hash_table.h"
#include "variables.h"
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <ctype.h>
int main(void){
char input[1000], sInput[1000]; // String to get user input
int count=1, len; // num=0;
struct Table *t;
t = TableCreate(); //create the table
int while_track;
FILE *ptr_file;
ptr_file =fopen(".simpleshell_history","a");
fclose(ptr_file);
printf("\nWelcome to the sample shell! You may enter commands here, one\n");
printf("per line. When you're finished, press Ctrl+D on a line by\n");
printf("itself. I understand basic commands and arguments separated by\n");
printf("spaces, redirection with < and >, up to two commands joined\n");
printf("by a pipe, tilde expansion, and background commands with &.\n\n");
printf("\npssh$ ");
while (fgets(input, sizeof(input), stdin)) {
strcpy(sInput, input);
len = strlen(input);
if( input[len-1] == '\n' ){
input[len-1] = '\0';
}
while_track = 1; // used to keep track of loop
while (while_track == 1){
count+=1;
if (strcmp(input, "history")==0){
while_track = History(); // print history function call
}else if (strcmp(input, "!!")==0){
while_track = Previous(input); // execute previous function call
}else if (strncmp(input, "!",1)==0){ // !string and !number sort
if(isdigit(input[1])){
while_track = Number(input);
} else {
while_track = String(input);
}
}else { // if the user entry was not any of specfic comnnad then pass the command to parse to execute
other(input,t);
parse(input);
while_track = 0;
}
}
HistoryFile(sInput); // A function call to recode commands entered by the user into a file
printf("\npssh$ ");
}
return 0;
}
hash_table.c
#include "hash_table.h"
#include <stdbool.h>
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <ctype.h>
void feedData(char * var, char * val, struct Table *t){
//const char * key=0;
printf("\n In FeedData Function\n");
Table_add(t, var, val);
printf("\nInside Feed Function -- Veriable: %s Value: %s\n",var, val);
}
unsigned int hash(const char *x) {
printf("\n In Hash\n");
int i;
unsigned int h = 0U;
printf("\n In Hash - Before for loop\n");
for (i=0; x[i]!='\0'; i++)
printf("\n In Hash - In for loop %d \n", i);
h = h * 65599 + (unsigned char)x[i];
printf("\n In Hash - In for loop - after calculation \n");
unsigned int g;
g = h % 1024;
printf("\n In Hash - In for loop - before return: %u \n",g);
return g;
}
struct Table *Table_create(void) {
printf("\n In Table_create\n");
struct Table *t;
t = (struct Table*)calloc(1, sizeof(struct Table));
return t;
}
void Table_add(struct Table *t, const char *key, char * val){
printf("\n In Table_add\n");
struct Node *p = (struct Node*)malloc(sizeof(struct Node));
int h = hash(key);
printf("\n In Table_add - after hash key\n");
//p->key = *key;
strcpy(p->key,key);
printf("\n In Table_add - after first key\n");
strcpy(p->value,val);
printf("\n In Table_add - after Value\n");
p->next = t->array[h];
printf("\n In Table_add - after p->next\n");
t->array[h] = p;
printf("\n In Table_add - after t->array[h] = p\n");
}
/*
int Table_search(struct Table *t, const char *key, int *value){
struct Node *p;
int h = hash(key); //---------------------------------------------------------------------
for (p = t->array[h]; p != NULL; p = p->next)
if (strcmp(p->key, key) == 0) {
*value = p->value;
return 1;
}
return 0;
}
*/
/*
void Table_free(struct Table *t) {
struct Node *p;
struct Node *nextp;
int b;
for (b = 0; b < BUCKET_COUNT; b++)
for (p = t->array[b]; p != NULL; p = nextp) {
nextp = p->next;
free(p);
}
free(t);
}
*/
hash_table.h file code
#ifndef HASH_TABLE_H
#define HASH_TABLE_H
struct Table *Table_create(void);
void Table_add(struct Table *t, const char *key, char * val);
unsigned int hash(const char *x);
void feedData(char * var, char * val, struct Table *t);
enum {BUCKET_COUNT = 1024};
struct Node {
char key[1000];
char variable[1000];
char value[1000];
struct Node *next;
};
struct Table {
struct Node *array[BUCKET_COUNT];
};
#endif

Warning 1: You are calling TableCreate while your function name is Table_create
Warning 2: After looking at new identifier followed by (, compiler assumes it is a function that takes variable number of arguments and returns int.

Related

C - Read word by word from a file and insert it in hashtable

I'm trying to use a chaining hashtable to count the number of repetition of all words in a .txt file.
So this is what I did, here's my header file:
#ifndef _header5_
#define _header5_
typedef struct cellule {
char cle[15]; // Cle=Word
int valeur; // Number of occurrences of the word
struct cellule *suivant;
} Cellule;
typedef Cellule * Liste; // type Liste
typedef struct table_hachage {
int taille; // table length
Liste *linkcase; // table of listes
} Table_hachage;
// type TableHacage
typedef Table_hachage *TableHachage;
/***************Methods*****/
int max(int,int);
int count_words (FILE*);
void read_words(FILE*);
TableHachage cree_table_hachage(int);
int hachage(TableHachage, char*);
int insere(TableHachage,char*);
int recherche(TableHachage, char*);
int Get_Value(TableHachage, char*);
void fill(TableHachage,FILE*);
#endif
and this is my implementation of the header file:
#include <stddef.h>
#include <stdlib.h>
#include <stdio.h>
#include <ctype.h>
#include <string.h>
#include "fnv.h"
#include "header5.h"
int max(int a,int b){
if(a>b)
return a;
else if(a<b)
return b;
else
return a;
}
int count_words (FILE *f) {
char word[1024];
int count=0;
/* assumes no word exceeds length of 1023 */
while (fscanf(f, " %1023s", word) == 1) {
count++;
}
return count;
}
void read_words(FILE *f) {
char word[1024];
/* assumes no word exceeds length of 1023 */
while (fscanf(f, " %1023s", word) == 1) {
puts(word);
}
}
//Create Empty chaining hashtable
TableHachage cree_table_hachage(int taille) {
int i;
TableHachage table = (TableHachage)malloc(sizeof(Table_hachage));
table->taille = taille;
table->linkcase = (Liste*)malloc(table->taille * sizeof(Liste));
for (i = 0; i < table->taille; i++)
table->linkcase[i] = NULL;
printf("HashTable is created\n");
return table;
}
//Getting the hash code using FNV1 Algorithm
//it works just fine by the way.
int hachage(TableHachage table, char *cle) {
//FNV HashCode Algorithm version 32-bits
int codeh = fnv_32_str(cle, FNV1_32_INIT);
return (abs(codeh) % table->taille);
}
//Insert the word in the hashtable
int insere(TableHachage table, char* cle) {
int codeh;
Liste liste = NULL;
codeh = hachage(table, cle); //getting the HashCode
liste = table->linkcase[codeh]; //getting the LinkedList at index==HashCode
while (liste) {
//In case the key is already existed we increment its value
//which indicates the number of repetition of that word
if (strcmp(liste->cle, cle) == 0){
liste->valeur++;
return 0;
}
liste = liste->suivant;
}
//if it's the first time to encounter the word
//we insert it and give it's value 1
if (liste == NULL) {
liste = (Liste)malloc(sizeof(Cellule));
strcpy(liste->cle, cle);
liste->valeur=1;
liste->suivant = table->linkcase[codeh];
table->linkcase[codeh] = liste;
return 1;
}
}
//Search existence of a word
int recherche(TableHachage table, char *cle){
Liste liste = table->linkcase[hachage(table, cle)];
for (; liste; liste = liste->suivant)
if (strcmp(cle, liste->cle) == 0)
return 1;
return 0;
}
//Getting value of a key a.k.a number of repetition of a word
int Get_Value(TableHachage table, char *cle){
Liste liste = table->linkcase[hachage(table, cle)];
for (; liste; liste = liste->suivant)
if (strcmp(cle, liste->cle) == 0)
return liste->valeur;
}
//Fill my hashcode with words and number of repetition of that key in the file
void fill(TableHachage table,FILE* f){
char word[1024];
/* assumes no word exceeds length of 1023 */
while (fscanf(f, " %1023s", word) == 1) {
insere(table,word);
}
}
So my problem resides in the fill() function, it is almost the same as read_word() function which works just fine except instead of printing the word, I want it to be inserted in the hash table.
When I checked which part doesn't work in fill() function, I realized it never goes into the while loop. So when I search for the word, it couldn't be found.
So can anyone explains this to me?
EDIT:
Here's my main():
#include <stdio.h>
#include <stdlib.h>
#include "fnv.h"
#include "header5.h"
/* run this program using the console pauser or add your own getch, system("pause") or input loop */
int main(int argc, char *argv[]) {
FILE *file=fopen("fich.txt", "r");
int n=count_words(file);
//Creating an empty chaining hash table
TableHachage T=cree_table_hachage(n);
//fill hash table with words and its number of repetition in the text file
fill(T,file);
//student is a word in my file
if(recherche(T,"student")==1){
printf("found\n");
}
else{
printf("couldn't be found\n");
}
int occ=Get_Value(T, "student");
printf("Occ is: %d\n",occ);
fclose(file);
return 0
}
As a solution for this problem this is what i did
#include <stdio.h>
#include <stdlib.h>
#include "fnv.h"
#include "header5.h"
/* run this program using the console pauser or add your own getch, system("pause") or input loop */
int main(int argc, char *argv[]) {
FILE *file=fopen("fich.txt", "r");
int n=count_wordsV2(file);
//printf("number of words is: %d\n",n);
fclose(file);
file=fopen("fich.txt", "r");
//Creating an empty chaining hash table
TableHachage T=cree_table_hachage(n);
//fill hash table with words and its number of repetition in the text file
fill(T,file);
//Get occurences of each word in text file
char* Max=Get_Occurences(T);
printf("The most repeated word is: \"%s\" with a value=%d\n",Max,Get_Value(T, Max));
//int occ=Get_Value(T,"pilots");
//printf("occ: %d\n",occ);
fclose(file);
return 0;
}

When freeing a pointer for a nested struct getting Segmentation fault

This is my code:
#include <stdio.h>
#include <ctype.h>
#include <string.h>
#include <stdlib.h>
#define NAMESIZE 20
#define LINESIZE 1024
typedef struct name name;
struct name
{
char last[NAMESIZE]; /* last name */
char first[NAMESIZE]; /* first name*/
};
typedef struct record record;
struct record
{
name name;
int score;
};
typedef struct record_list record_list;
struct record_list
{
record *data; /* the dynamic array of records */
size_t nalloc; /* number of records allocated */
size_t nused; /* number of records in use */
};
void list_init(record_list *list)
{
list -> data = 0;
list -> nalloc = 0;
list -> nused = 0;
}
int list_insert(record_list *list, const record *rec)
{
size_t newSize;
record *tmp;
if(list -> nalloc == list -> nused)
{
if(list -> nalloc == 0)
{
newSize = 1;
}
else
{
newSize = 2 * list -> nalloc;
}
tmp = realloc(list -> data, newSize * sizeof(record));
if(tmp == 0)
{
return 0;
}
list -> data = tmp;
list -> nalloc = newSize;
}
list -> data[list -> nused++] = *rec;
return 1;
}
void list_destroy(record_list *list)
{
printf("Attempting Deletion");
free(list->data);
free(list->nalloc);
free(list->nused);
list -> data = 0;
list -> nalloc = 0;
list -> nused = 0;
}
int main(void){
record_list list;
record *r;
name n;
int score;
char input[NAMESIZE];
char name[NAMESIZE];
char lname[NAMESIZE];
list_init(&list);
while(input != NULL) {
printf("Please enter a value for Name: ");
scanf("%s", input);
strcpy(input, name);
printf("Enter last name: ");
scanf("%s", input);
strcpy(input, lname);
printf("Enter score: ");
scanf("%d", &score);
r=(record*)malloc(sizeof(record));
if(r == NULL){
printf("There isn't enough memory.\n");
}
strcpy(n.first, name);
strcpy(n.last, lname);
r -> name = n;
list_insert(&list, r);
printf("\n");
printf("Choose next action:\n");
printf("\tTo add more type \"add\";\n");
printf("\tTo delete all records type \"del\";\n");
scanf("%s", input);
if(strcmp(input, "del") == 0){
list_destroy(&list);
printf("Deleted");
break;
}
}
return 1;
}
I am working on a small lab exercise where we make a struct, fill it and clear it if the user needs to. Yesterday everything worked but today I seem to either have not saved it or broke something because I am getting a ton of errors.
Here is an example of the error I'm getting:
Essentially when I call a method
void list_destroy(record_list *list);
it crashes before reaching the first print statement which means I am doing something wrong with the method call.
Summarized question: What could be causing the segmentation fault (where am I accessing incorrect memory) Or how else can I clear my struct memory without using free?
Thank you very much.
This should tell what your problem is:
code.c: In function 'list_destroy':
code.c:74: warning: passing argument 1 of 'free' makes pointer from integer without a cast
code.c:75: warning: passing argument 1 of 'free' makes pointer from integer without a cast
You're trying to free int fields. You can't free them because they are not pointers to memory blocks.
So, remove these lines of code:
free(list->nalloc);
free(list->nused);

Hash Table - Sort Structure with qsort

Alright sorry for creating another question but the last one got overwhelmed and chaotic.
So I'm making a hash table which inserts words from a file (tokens) and after I have inserted them I need to sort them. The program template was given, the only functions that weren't complete were : insert_ht() , clear_ht() and compare. Even though I've done tons of search about qsort with compare, the program doesn't sort the frequencies (number of times each word was inserted) . I want em sorted from the highest to lowest.
Here is the code : "note that i shouldn't change any function except insert_ht() , clear_ht() and compare
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <ctype.h>
#define HTABLE_SIZ 1001
#define MAX_LINE_SIZ 1024
/* Hash Table */
typedef struct node* link;
struct node { char *token; int freq; link next; };
link htable[HTABLE_SIZ] = { NULL }; /* Table of lists (#buckets) */
int size = 0; /* Size (number of elements) of hash table */
unsigned int hash (char *tok );
void insert_ht (char *data);
void clear_ht ( );
void print_ht ( );
void Process(FILE *fp);
int main(int argc, char *argv[])
{
int i;
FILE *fp;
printf("prin tin for \n");
for (i=1; i < argc; i++)
{
printf("prin tin fopen \n");
fp = fopen(argv[i],"r");
if (NULL == fp)
{
fprintf(stderr,"Problem opening file: %s\n",argv[i]);
continue;
}
printf("prin tin process \n");
Process(fp);
fclose(fp);
}
print_ht();
//clear_ht();
return 0;
}
void Process(FILE *fp)
{
const char *seperators = " ?!'\";,.:+-*&%(){}[]<>\\\t\n";
char line[MAX_LINE_SIZ];
char *s;
while((fgets(line,MAX_LINE_SIZ, fp)) != NULL)
{
for (s=strtok(line,seperators); s; s=strtok(NULL,seperators)){
printf("prin tin insert %s \n",s);
insert_ht(s);
}
}
}
/* Hash Function */
unsigned int hash(char *tok)
{
printf("bike stin hash \n");
unsigned int hv = 0;
while (*tok)
hv = (hv << 4) | toupper(*tok++);
printf("VGAINEIIIIIIIIIIIIII %d \n",hv);
return hv % HTABLE_SIZ;
}
void insert_ht(char *token)
{
printf("bike stin insert %s \n",token);
unsigned int hashval = hash(token);
struct node *new_list;
if (htable[hashval]==NULL){
printf("mesa stin prwti if %u %s \n",hashval,token);
//token = strdup(token);
new_list = malloc(sizeof(link));
new_list->token = strdup(token) ;
new_list->freq = 1;
new_list->next = htable[hashval];
htable[hashval] = new_list;
size++;
}else {
htable[hashval]->freq++;
}
printf("ta evale epitixws \n");
}
void clear_ht()
{
int i;
for(i=0; i<HTABLE_SIZ; i++) {
while(htable[i]->token!=NULL) {
htable[i]->token=NULL;
htable[i]->freq=NULL;
free(htable[i]);
}
}
}
int compare(const void *elem1, const void *elem2)
{
const struct node *p1 = elem1;
const struct node *p2 = elem2;
if (p1->freq > p2->freq)
return(+1);
else if (p1->freq < p2->freq)
return(-1);
else
return(0);
}
void print_ht()
{
int i, j=0;
link l, *vector = (link*) malloc(sizeof(link)*size);
for (i=0; i < HTABLE_SIZ; i++)
for (l=htable[i]; l; l=l->next)
vector[j++] = l;
qsort(vector,size,sizeof(link),compare);
for (i=0; i < size; i++)
printf("%-50s\t%7d\n",vector[i]->token,vector[i]->freq);
free(vector);
}
Ι found the solution. Apparently for some reason my compare function was wrong.
I still haven't figured out why but here is the correct one, hopefully someone else will find this post helpful!
int compare(const void *elem1, const void *elem2)
{
return (*(link*)elem2)->freq - (*(link*)elem1)->freq;
}

Hash Table in C (find the frequency of every word)

I want to create a hash table for an exercise I have to send in my University.
The program will open a number of files, break each file's content to <<words>> (tokens) and it will save each <<word>> in a hash table with the frequency of each <<word>>.
In case the word is already in the hash table , the program will increase the word's frequency.
At the end the program will print the words and it's frequencies accordingly.
Also the frequencies should be printed from the highest word frequency to the lowest.
The comparison of the <<words>> will ignore upper and lower case letters.
For example if a file contains : one two three four Two Three Four THREE FOUR FoUr
It should print:
four 4
three 3
two 2
one 1
The professor gave us a template that we should complete but I'm really confused on what to do with the insert_ht() and clear_ht() functions as well as the compare one.
Here is the code :
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <ctype.h>
#define HTABLE_SIZ 1001
#define MAX_LINE_SIZ 1024
/* Hash Table */
typedef struct node* link;
struct node { char *token; int freq; link next; };
link htable[HTABLE_SIZ] = { NULL }; /* Table of lists (#buckets) */
int size = 0; /* Size (number of elements) of hash table */
unsigned int hash (char *tok );
void insert_ht (char *data);
void clear_ht ( );
void print_ht ( );
void Process(FILE *fp);
int main(int argc, char *argv[])
{
int i;
FILE *fp;
for (i=1; i < argc; i++)
{
fp = fopen(argv[i],"r");
if (NULL == fp)
{
fprintf(stderr,"Problem opening file: %s\n",argv[i]);
continue;
}
Process(fp);
fclose(fp);
}
print_ht();
clear_ht();
return 0;
}
void Process(FILE *fp)
{
const char *seperators = " ?!'\";,.:+-*&%(){}[]<>\\\t\n";
char line[MAX_LINE_SIZ];
char *s;
while((fgets(line,MAX_LINE_SIZ, fp)) != NULL)
{
for (s=strtok(line,seperators); s; s=strtok(NULL,seperators))
insert_ht(s);
}
}
/* Hash Function */
unsigned int hash(char *tok)
{
unsigned int hv = 0;
while (*tok)
hv = (hv << 4) | toupper(*tok++);
return hv % HTABLE_SIZ;
}
void insert_ht(char *token)
{
……………………………………………
}
void clear_ht()
{
……………………………………………
}
int compare(const void *elem1, const void *elem2)
{
……………………………………………
}
void print_ht()
{
int i, j=0;
link l, *vector = (link*) malloc(sizeof(link)*size);
for (i=0; i < HTABLE_SIZ; i++)
for (l=htable[i]; l; l=l->next)
vector[j++] = l;
qsort(vector,size,sizeof(link),compare);
for (i=0; i < size; i++)
printf("%-50s\t%7d\n",vector[i]->token,vector[i]->freq);
free(vector);
}
I'll answer you in a new post because it's hard to be exhaustive in comments.
1. Malloc
Why would I need to use malloc then ? Shouldn't i write directly to the htable? (on the insert_ht() funtion)
You need to use malloc because you declare a char pointer in struct (char *token). The thing is that you never initialize the pointer to anything, and as far you don't know the size of the token, you need to malloc every token. But, as you use strdup(token), you don't need to malloc token because strdup does. So don't forget to free every token in order to avoid memory leaks.
2. Segfault
I can't test you code, but it seems like the following line causes the segmentation fault :
list = htable[hashval]->token
Indeed, you try to access token while htable[hashval] is NULL, and to assign a char * to a link type (list).
You need to loop with this :
for(list = htable[hashval]; list != NULL; list = list->next) { ... }
3. Notes
if (x=1) should be if(x==1).
Don't malloc new_list if you don't need to.
Because new_list if used when htable[hashval] is NULL, new_list->next = htable[hashval]; will set new_list->next to NULL.
You should use the -Wall option in gcc (for warnings) and you may use valgrind to understand your segmentation faults. In this case, use gcc with debug mode (-g).
Double and Final edit : Ι found the solution. Apparently for some reason my compare function was wrong.
I still haven't figured out why but here is the correct one, hopefully someone else will find this post helpful!
int compare(const void *elem1, const void *elem2)
{
return (*(link*)elem2)->freq - (*(link*)elem1)->freq;
}
Edit: deleted old answer . Found the correct way I think but I have another problem right now.
The compare function doesn't work correctly. My printf is fine but it doesnt sort them with the frequiencies. I want them to be sorted from the highest to lowest .
In this example: the file contains -> one two three four Two Three Four THREE FOUR FoUr
And I get:
two 2
one 1
four 4
three 3
While I should be getting :
four 4
three 3
two 2
one 1
Here is the code. Feel free to help!
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <ctype.h>
#define HTABLE_SIZ 1001
#define MAX_LINE_SIZ 1024
/* Hash Table */
typedef struct node* link;
struct node { char *token; int freq; link next; };
link htable[HTABLE_SIZ] = { NULL }; /* Table of lists (#buckets) */
int size = 0; /* Size (number of elements) of hash table */
unsigned int hash (char *tok );
void insert_ht (char *data);
void clear_ht ( );
void print_ht ( );
void Process(FILE *fp);
int main(int argc, char *argv[])
{
int i;
FILE *fp;
printf("prin tin for \n");
for (i=1; i < argc; i++)
{
printf("prin tin fopen \n");
fp = fopen(argv[i],"r");
if (NULL == fp)
{
fprintf(stderr,"Problem opening file: %s\n",argv[i]);
continue;
}
printf("prin tin process \n");
Process(fp);
fclose(fp);
}
print_ht();
//clear_ht();
return 0;
}
void Process(FILE *fp)
{
const char *seperators = " ?!'\";,.:+-*&%(){}[]<>\\\t\n";
char line[MAX_LINE_SIZ];
char *s;
while((fgets(line,MAX_LINE_SIZ, fp)) != NULL)
{
for (s=strtok(line,seperators); s; s=strtok(NULL,seperators)){
printf("prin tin insert %s \n",s);
insert_ht(s);
}
}
}
/* Hash Function */
unsigned int hash(char *tok)
{
printf("bike stin hash \n");
unsigned int hv = 0;
while (*tok)
hv = (hv << 4) | toupper(*tok++);
printf("VGAINEIIIIIIIIIIIIII %d \n",hv);
return hv % HTABLE_SIZ;
}
void insert_ht(char *token)
{
printf("bike stin insert %s \n",token);
unsigned int hashval = hash(token);
if (htable[hashval]==NULL){
printf("mesa stin prwti if %u %s \n",hashval,token);
//token = strdup(token);
htable[hashval] = malloc(sizeof(token));
htable[hashval]->token = token ;
htable[hashval]->freq = 1;
size++;
}else {
htable[hashval]->freq++;
}
printf("ta evale epitixws \n");
}
int compare(const void *elem1, const void *elem2)
{
const struct node *p1 = elem1;
const struct node *p2 = elem2;
if ( p1->freq < p2->freq)
return -1;
else if (p1->freq > p2->freq)
return 1;
else
return 0;
}
void print_ht()
{
int i, j=0;
link l, *vector = (link*) malloc(sizeof(link)*size);
for (i=0; i < HTABLE_SIZ; i++)
for (l=htable[i]; l; l=l->next)
vector[j++] = l;
qsort(vector,size,sizeof(link),compare);
for (i=0; i < size; i++)
printf("%-50s\t%7d\n",vector[i]->token,vector[i]->freq);
free(vector);
}
Sorry for my bad english.
I think that :
insert(char *token) takes a word of the file and puts into the hash table. In brief, if the word exists in the hash table, you just have to increment its frequencie. Otherwise, you need to create another node and put the frequencie to 1, then ad it to the array. At the end, you will have one entry for each unique word.
compare(const void *elem1, const void *elem2) will be used by qsort. It returns 0 if elem1 = elem2, a negative number if elem1 < elem2 and a number > 0 if elem1 > elem2. By passing compare to qsort, you allow qsort to sort you array according to your own criteria.
clear_ht() may set all the values of the array to NULL, in order to restart another count ?

Array of Structs strange output?

Can anyone give me some indication as to why array of structs doesn't print out properly ?
I think its something to do with the memory I have allocated to the struct I am unsure !!
Using mac osx mountain lion xcode 4 gcc
Thanks for any help completely stuck!!
(Please have patience I am only a student !)
#include <stdio.h>
#include <limits.h>
#include <ctype.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
typedef struct{
char* one;
char* two;
} Node;
Node *nodes;
int count = 0;
//-----------------------------------------------------------------------
void add(char *one,char*two){
char x[40];
char y[40];
printf("reached..\n");
strcpy(x,one);
strcpy(y,two);
printf("--> X: %s\n",x);
printf("--> Y: %s\n",y);
Node newNode;
newNode.one = x;
newNode.two = y;
nodes[count]= newNode;
count++;
}
//-----------------------------------------------------------------------
//-----------------------------------------------------------------------
void print(){
int x;
for (x = 0; x < 10; x++)
{
printf("%d : (%s, %s) \n",x,nodes[x].one, nodes[x].two);
}
}
//-----------------------------------------------------------------------
//-----------------------------------------------------------------------
void check(char **arg)
{
if(strcmp(*arg, "Add") == 0)
{
add(arg[1],arg[2]);
}else if(strcmp(*arg,"print") == 0)
{
print();
}else{
printf("Error syntax Enter either: \n Add [item1][item2]\n OR \n print\n");
}
}
//-----------------------------------------------------------------------
void readandParseInput(char *line,char **arg)
{
if (fgets (line, 512, stdin)!= NULL) {
char * pch;
pch = strtok (line," \n\t");
int count = 0;
arg[0] = pch;
while (pch != NULL)
{
count++;
pch = strtok (NULL, " \n\t");
arg[count] =pch;
}
}else{
printf("\n");
exit(0);
}
}
//-----------------------------------------------------------------------
int main()
{
int size = 100;
nodes = calloc(size, sizeof(Node));
int i;
for(i = 0;i <100; i++){
printf("%s , %s \n",nodes[i].one,nodes[i].two );
// nodes[i].one = ".";
// nodes[i].two = ".";
}
char line[512]; /* the input line */
char *arg[50]; /* the command line argument */
while (1)
{
readandParseInput(line,arg);
if(arg[0] != NULL){
check(arg);
}
}
return(0);
}
You're keeping pointers to the following automatic variables:
char x[40];
char y[40];
These go out of scope when add() returns, leaving you with dangling pointers.
You either have to turn Node::one and Node::two into arrays, or allocate memory for them on the heap.
In you add() function, you cannot assign one struct to another via an = operator... you would have to copy it...
memcpy( &nodes[count], &newNode )
#include <stdio.h>
#include <stdlib.h>
typedef struct {
char *fn;
}NAME;
#define NAME_LEN 20
int main()
{
NAME name;
name.fn = (char *) calloc(NAME_LEN, sizeof(char));
strcpy(name.fn, "Namco");
printf("Name: %s\n", name.fn);
free(name.fn);
return 0;
}
you can't just assign a string like this in c
newNode.one = x;
newNode.two = y;
what is newNode.one referring to???
at Function add
newNode.one = x;
newNode.two = y;
to
newNode.one = strdup(x);
newNode.two = strdup(y);

Resources