pointer called by reference doesnt work - c

Hi i have a problem with the next code which i had posted before here, but yesterday i was working on my computer and all of the sudden the screen froze and when i restarted it my code was gone!! it was erased, so i had to start over. The code had to search a codop in a linked list, but it doesnt work, i keep getting the message "CODOP NOT FOUND", i thought that the problem was in the calling of pointers as pass by value, so i called it by reference but it doesnt work either, if someone could tell me how to solve it i would apreciate it a lot
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef struct node
{
char *instruction;
struct node *next;
}COD;
void printList(COD *head);
void SearchEndLine(FILE *hc12);
void listTABOP(COD **head);
COD *lastElement(COD **head);
COD *createNode(char *ins);
void insertEnd(char *ins,COD *last);
char *Operands_Table(FILE *hc12);
COD *searchCodop(COD *head,char *codop);
void Remove(char *c);
int main()
{
COD *head = NULL,*found = NULL;
char *codop = "BLE";
listTABOP(&head);
printList(head);
if((found = searchCodop(head,codop)) == NULL)
{
printf("CODOP NOT FOUND\n");
printf("%s\n",codop);
}
return 0;
}
void SearchEndLine(FILE *hc12)
{
int car;
while((car = fgetc(hc12))!= '\n')
;
}
void Remove(char *c)
{
char *ptr;
if(((ptr = strchr(c,'\n'))!= NULL)||((ptr = strchr(c,'\t'))!= NULL)||((ptr = strchr(c,' '))!= NULL))
*ptr = '\0';
}
void listTABOP(COD **head)
{
int car;
FILE *hc12;
COD *last = NULL;
char *ins;
if((hc12 = fopen("Tabla_OP.txt","r"))!= NULL)
{
while((car = fgetc(hc12))!= EOF)
{
if(car != '\t')
{
ins = Operands_Table(hc12);
if(*head == NULL)
*head = createNode(ins);
else
{
last = lastElement(head);
insertEnd(ins,last);
}
}
else
SearchEndLine(hc12);
}
}
else
printf("No se pudo abrir el archivo");
}
COD *lastElement(COD **head)
{
COD *ptr;
ptr = *head;
while(ptr->next != NULL)
ptr = ptr->next;
return ptr;
}
char *Operands_Table(FILE *hc12)
{
int car,lon = 0,pos;
char *c;
fseek(hc12,-1,SEEK_CUR);
pos = ftell(hc12);
do
{
car = fgetc(hc12);
lon++;
}while(car != '\t');
fseek(hc12,pos,SEEK_SET);
c = (char*)calloc((lon+1),sizeof(char));
fgets(c,lon+1,hc12);
Remove(c);
SearchEndLine(hc12);
return c;
}
COD *searchCodop(COD *head,char *codop)
{
COD *ptr;
for(ptr = head;ptr != NULL;ptr = ptr->next)
{
if(ptr->instruction == codop)
return ptr;
}
return NULL;
}
void insertEnd(char *ins,COD *last)
{
last->next = createNode(ins);
last->next->next = NULL;
last = last->next;
}
COD *createNode(char *ins)
{
int s;
COD *x;
x = (COD*)malloc(sizeof(COD));
s = strlen(ins);
x->instruction = (char*)malloc((s+1)*sizeof(char));
strcpy(x->instruction,ins);
x->next = NULL;
return x;
}
void printList(COD *head)
{
COD *ptr;
for(ptr = head;ptr != NULL;ptr = ptr->next)
printf("\n%s\n",ptr->instruction);
}

The problem is with this line:
if(ptr->instruction == codop)
it compares address of strings not strings themselves.
Use strcmp or something like that instead.

Related

Variable value changing after returning to the loop

I've been coding for a C - Binary Search Tree, but the Program always change variable when returning to the loop. I've tried debugging it and checked every pointer but found no errors.
There is a simple run(bold for input, italic for notes)
a
Please enter name of pet:
aaa //pet name, input
Please enter pet kind:
bbb //pet kind, input
add pet success
aaa //pet name, is correct
//pet kind, return to 0
q
0b //pet name, turn to 0b
//pet kind, always 0
Bye.
The code is the next:
main.c
#include "tree.h"
#define CHECK
char menu(void);
void addpet(Tree *pt);
char *s_gets(char *st, int n);
int main(void)
{
Tree pets;
char choice;
InitializeTree(&pets);
while ((choice = menu()) != 'q')
{
switch (choice)
{
case 'a':
addpet(&pets);
#ifdef CHECK
printf("%s", pets.root->head->petname);
printf("%s", pets.root->head->petkind); // petkind back to 0
#endif
break;
default:
puts("Switching error");
}
}
#ifdef CHECK
puts(pets.root->head->petname); // trun to '\000' '372' '\333' 'b' '\376' '\177'
puts(pets.root->head->petkind); // always 0
#endif
puts("Bye.");
return 0;
}
char menu(void)
{
int ch;
ch = getchar();
while (getchar() != '\n')
continue;
return ch;
}
void addpet(Tree *pt)
{
Item temp;
if (TreeIsFull(pt))
puts("No room in the club!");
else
{
puts("Please enter name of pet:");
s_gets(temp.petname, SLEN);
puts("Please enter pet kind:");
s_gets(temp.petkind, SLEN);
temp.next = NULL;
if (AddItem(&temp, pt))
puts("add pet success");
}
}
char *s_gets(char *st, int n)
{
char *ret_val;
char *find;
ret_val = fgets(st, n, stdin);
if (ret_val)
{
find = strchr(st, '\n');
if (find)
*find = '\0';
else
while (getchar() != '\n')
continue;
}
return ret_val;
}
tree.c
#include "tree.h"
static Node *MakeNode(Item *pi);
static bool ToLeftNode(const Node *i1, const Node *i2);
static bool ToRightNode(const Node *i1, const Node *i2);
static void AddNode(Node *new_node, Node *root);
static PairNode SeekNode(const Node *pn, const Tree *ptree);
static PairItem SeekList(Node *, const Item *);
void InitializeTree(Tree *ptree)
{
ptree->root = NULL;
ptree->size = 0;
}
bool TreeIsFull(const Tree *ptree)
{
if (ptree->size == MAXITEMS)
return true;
else
return false;
}
bool AddItem(Item *pi, Tree *ptree)
{
Node *new_node;
PairNode seek_node;
PairItem seek_list;
if (TreeIsFull(ptree))
{
fprintf(stderr, "Tree is full\n");
return false;
}
new_node = MakeNode(pi);
if (new_node == NULL)
{
fprintf(stderr, "Couldn't create node\n");
return false;
}
if ((seek_node = SeekNode(new_node, ptree)).child != NULL)
{
if ((seek_list = SeekList(seek_node.child, pi)).child != NULL)
{
fprintf(stderr, "Attempted to add duplicate item\n");
return false;
}
seek_list.child = pi;
ptree->size++;
return true;
}
ptree->size++;
if (ptree->root == NULL)
ptree->root = new_node;
else
AddNode(new_node, ptree->root);
return true;
}
static void AddNode(Node *new_node, Node *root)
{
if (ToLeftNode(new_node, root))
{
if (root->left == NULL)
root->left = new_node;
else
AddNode(new_node, root->left);
}
else if (ToRightNode(new_node, root))
{
if (root->right == NULL)
root->right = new_node;
else
AddNode(new_node, root->right);
}
else
{
fprintf(stderr, "location error in AddNode()\n");
exit(1);
}
}
static bool ToLeftNode(const Node *i1, const Node *i2)
{
if (strcmp(i1->petname, i2->petname) < 0)
return true;
else
return false;
}
static bool ToRightNode(const Node *i1, const Node *i2)
{
if (strcmp(i1->petname, i2->petname) > 0)
return true;
else
return false;
}
static Node *MakeNode(Item *pi)
{
Node *new_node;
new_node = (Node *)malloc(sizeof(Node));
if (new_node != NULL)
{
strcpy(new_node->petname, pi->petname);
new_node->head = pi;
new_node->left = NULL;
new_node->right = NULL;
}
return new_node;
}
static PairNode SeekNode(const Node *pn, const Tree *ptree)
{
PairNode look;
look.parent = NULL;
look.child = ptree->root;
if (look.child == NULL)
return look;
while (look.child != NULL)
{
if (ToLeftNode(pn, look.child))
{
look.parent = look.child;
look.child = look.child->left;
}
else if (ToRightNode(pn, look.child))
{
look.parent = look.child;
look.child = look.child->right;
}
else
break;
}
return look;
}
static PairItem SeekList(Node *pn, const Item *pi)
{
PairItem seek;
seek.child = pn->head;
seek.parent = NULL;
while (seek.child != NULL)
{
if (strcmp(seek.child->petname, pi->petname) == 0 &&
strcmp(seek.child->petkind, pi->petkind) == 0)
break;
seek.parent = seek.child;
seek.child = seek.child->next;
}
return seek;
}
tree.h
#ifndef TREE_H_
#define TREE_H_
#define SLEN 20
#define MAXITEMS 10
#include <ctype.h>
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef struct item{ char petname[SLEN]; char petkind[SLEN]; struct item *next;} Item;
typedef struct node{ char petname[SLEN]; Item *head; struct node *left; struct node *right;} Node;
typedef struct tree{ Node *root; int size;} Tree;
typedef struct pairnode{ Node *parent; Node *child;} PairNode;
typedef struct pairitem{ Item *parent; Item *child;} PairItem;
void InitializeTree(Tree *ptree);
bool AddItem(Item *pi, Tree *ptree);
#endif
My question was answered elsewhere.
Modify function addpet:
void addpet(Tree* pt)
{
Item* temp = (Item*)malloc(sizeof(Item));
puts("Please enter name of pet:");
s_gets(temp->petname, SLEN);
puts("Please enter pet kind:");
s_gets(temp->petkind, SLEN);
temp->next = NULL;
if (AddItem(temp, pt))
puts("add pet success");
}

Defining list and inner dictionary as the value of a dictionary in c

I am very new in c language and I am so sorry if my question is too basic.
I want to define a dictionary in c in which I have a list as the value of my keys. In other word, I like to have something like this is python in c:
my_dictionary = {1:{'name':'john','items':['item1','item2']},2:{'name':'bob','items':['item3','item4']}}
Then I like to have access to my defined dictionary as this:
my_item = my_dictionary[1]['items'].
I know this is very easy in python but for c, I could not find a good example for this. I am able to define simple dictionaries such as:
typedef struct dict_t_struct {
char *key;
void *value;
struct dict_t_struct *next;
} dict_t;
and I can easily add, remove, or print items from this dictionary using below functions:
dict_t **dictAlloc(void) {
return malloc(sizeof(dict_t));
}
void dictDealloc(dict_t **dict) {
free(dict);
}
void *getItem(dict_t *dict, char *key) {
dict_t *ptr;
for (ptr = dict; ptr != NULL; ptr = ptr->next) {
if (strcmp(ptr->key, key) == 0) {
return ptr->value;
}
}
return NULL;
}
void delItem(dict_t **dict, char *key) {
dict_t *ptr, *prev;
for (ptr = *dict, prev = NULL; ptr != NULL; prev = ptr, ptr = ptr->next) {
if (strcmp(ptr->key, key) == 0) {
if (ptr->next != NULL) {
if (prev == NULL) {
*dict = ptr->next;
} else {
prev->next = ptr->next;
}
} else if (prev != NULL) {
prev->next = NULL;
} else {
*dict = NULL;
}
free(ptr->key);
free(ptr);
return;
}
}
but the problem is that I need to have linked list as the values of my dictionary and an inner dictionary in my dictionary.
1 Your structure is json, you can't use the normal dictionary completely
2 If you need to store a list, you need to define the data structure of the list.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define DICT_STRING 1
#define DICT_LIST 2
typedef struct list_node {
void* value;
struct list_node* next;
} list_node;
typedef struct list {
list_node* head;
} list;
typedef struct dict_entry {
int type;
char* key;
void* value;
struct dict_entry* next;
} dict_entry;
typedef struct dict_t {
dict_entry* head;
} dict_t;
dict_t* dictAlloc(void) {
dict_t* d = malloc(sizeof(dict_t));
d->head = NULL;
return d;
}
void dictDealloc(dict_t* dict) {
free(dict);
}
dict_entry* addItem(dict_t* dict, int type, char* key, void* value) {
dict_entry* de = malloc(sizeof(*de));
de->type = type;
de->key = key;
de->value = value;
de->next = dict->head;
dict->head = de;
return de;
}
dict_entry* getItem(dict_t* dict, char* key) {
dict_entry* de = dict->head;
while (de) {
if (strcmp(de->key, key) == 0) {
return de;
}
de = de->next;
}
return NULL;
}
int main(int argc, char** argv) {
dict_t* d = dictAlloc();
dict_entry* de;
list* l = malloc(sizeof(*l));
list_node* n = malloc(sizeof(*n));
n->value = "value";
l->head = n;
addItem(d, DICT_LIST, "key", l);
de = getItem(d, "key");
switch (de->type) {
case DICT_LIST: {
list* l = de->value;
printf("%s", l->head->value);
}
}
}

Program sorts the data in the wrong way

I have to wirte a project for school, here is Program description
As can you see in the program description i have to sort the books by labels. Right now for some reason books that do not belong to specific label are printed under that label. For exemple Plato is printed under medival
I cannot find where did I made a mistake, I will be grateful for any help.
Here is my code:
#define _CRT_SECURE_NO_WARNINGS
#define _CRTDBG_MAP_ALLOC
#include <stdlib.h>
#include <crtdbg.h>
#include <stdio.h>
#include <string.h>
typedef struct BOOK Book;
struct BOOK
{
char *author;
char *title;
Book *next;
};
typedef struct LABEL Label;
struct LABEL
{
char *text;
Label *next;
Book *books;
};
void clear(Label** head);
void addLabel(Label **head, Label *elem);
void addBook(Book **head, Book **elem);
void readFromFile(char *fileName, char *outputFileName, Label *Ihead);
void saveBooks(FILE *file, Book *head);
void saveLabels(FILE *file, Label *Ihead);
void saveToFile(char *fileName, Label *Ihead);
void ComandConsole(int argc, char* argv[], int* fileinput, int* fileoutput);
Label* checkIfExists(Label **head, char *labelText);
Label* checkIfExists(Label **head, char *labelText)
{
Label *tmp = *head;
while (tmp != NULL)
{
if (strcmp(labelText, tmp->text) == 0)
return tmp;
tmp = tmp->next;
}
return NULL;
}
void addLabel(Label **head, Label *elem)
{
Label *temp = NULL;
if ((temp = checkIfExists(head, elem->text)) == NULL)
{
if (*head == NULL)
{
*head = elem;
return;
}
temp = *head;
while (temp->next != NULL)
temp = temp->next;
temp->next = elem;
}
else
addBook(&(temp->books), &(elem->books));
}
void addBook(Book **head, Book **elem)
{
Book *pom = *head;
if (strcmp(pom->author, (*elem)->author) > 0)
{
(*elem)->next = (*head)->next;
*head = *elem;
*elem = pom;
(*head)->next = *elem;
return;
}
while (pom->next != NULL && (strcmp((*elem)->author, pom->author) > 0))
pom = pom->next;
(*elem)->next = pom->next;
pom->next = *elem;
}
void readFromFile(char *fileName, char *outputFileName, Label *head)
{
FILE* input;
if ((input = fopen(fileName, "r")) == NULL)
{
printf("Reading failed!\n");
exit(1);
}
char buf[255];
while (fgets(buf, sizeof buf, input) != NULL)
{
Book *ksiazka = (Book*)malloc(sizeof(Book));
ksiazka->next = NULL;
char *store = strtok(buf, ";");
char * autor = (char*)malloc(sizeof(char)*strlen(store) + 1);
strcpy(autor, store);
ksiazka->author = autor;
store = strtok(NULL, ";");
char * tytul = (char*)malloc(sizeof(char)*strlen(store) + 1);
strcpy(tytul, store);
ksiazka->title = tytul;
store = strtok(NULL, "\n");
char * label = (char*)malloc(sizeof(char)*strlen(store) + 1);
strcpy(label, store);
char *tmp = strtok(label, ",\n");
while (tmp != NULL)
{
Label *newLabel = (Label*)malloc(sizeof(Label));
newLabel->books = NULL;
newLabel->next = NULL;
char *labelText = (char*)malloc(sizeof(char)*strlen(tmp) + 1);
strcpy(labelText, tmp);
newLabel->text = labelText;
newLabel->books = ksiazka;
addLabel(&head, newLabel);
tmp = strtok(NULL, ",\n");
}
}
saveToFile(outputFileName, head);
fclose(input);
}
void clear(Label** head)
{
while (*head != NULL)
{
Label* cur = *head;
*head = (*head)->next;
Book* a = cur->books;
while (a != NULL)
{
Book* b = a;
a = a->next;
free(b->author);
free(b->title);
free(b);
}
free(cur->text);
free(cur);
}
}
void saveBooks(FILE *file, Book *head)
{
Book *tmp = head;
while (tmp != NULL)
{
fprintf(file, "%s, %s\n", tmp->author, tmp->title);
tmp = tmp->next;
}
fprintf(file, "\n");
}
void saveLabels(FILE *file, Label *head)
{
Label *tmp = head;
while (tmp != NULL)
{
fprintf(file, "%s:\n", tmp->text);
if (tmp->books != NULL)
{
saveBooks(file, tmp->books);
}
tmp = tmp->next;
}
}
void saveToFile(char *fileName, Label *head)
{
FILE *output;
if ((output = fopen(fileName, "w")) == NULL)
{
printf("Writing failed!\n");
exit(1);
//clear(&head);
}
else
{
saveLabels(output, head);
}
//clear(&head);
fclose(output);
}
void ComandConsole(int argc, char* argv[], int* fileinput, int* fileoutput)
{
int i;
for (i = 1; i < argc; i++)
{
if (argv[i][0] == '-')
switch (argv[i][1])
{
case 'i':
{
i++;
if (i == argc) break;
*fileinput = i;
}
break;
case 'o':
{
i++;
if (i == argc) break;
*fileoutput = i;
}
break;
default:
{
printf("Wrong parameter");
} break;
}
}
}
int main(int argc, char* argv[])
{
int fileinputname = 0;
int fileoutputname = 0;
ComandConsole(argc, argv, &fileinputname, &fileoutputname);
if (fileinputname == 0 || fileoutputname == 0)
{
printf("Wrong parrametes");
getchar();
return 1;
}
Label *head = NULL;
readFromFile(argv[fileinputname], argv[fileoutputname], head);
_CrtDumpMemoryLeaks();
return 0;
}

Making strcpy function with linked list in c

I was making my own strcpy function using linked list but couldn't get how to do.
Without using linked list it could be like this
char* cp2014strcpy(char * dest_ptr, const char * src_ptr) {
char* strresult = dest_ptr;
if((NULL != dest_ptr) && (NULL != src_ptr)) {
while (NULL != src_ptr) {
*dest_ptr++ = *src_ptr++;
}
*dest_ptr = NULL;
}
return strresult;
}
but I couldn't get how to make strcpy using linked list.
#include <stdio.h>
#include <stdlib.h>
typedef struct node {
char ch;
struct node *next;
} LL_str;
LL_str *LL_new(char ch){
LL_str *s = malloc(sizeof(*s));//check omitted
s->ch = ch;
s->next = NULL;
return s;
}
LL_str *s_to_LL(const char *s){
LL_str *top, *curr;
if(!s || !*s)
return NULL;
curr = top = LL_new(*s);
while(*++s){
curr = curr->next = LL_new(*s);
}
return top;
}
LL_str *LL_strcpy(const LL_str *s){//LL_strdup ??
LL_str *top, *curr;
if(!s)
return NULL;
curr = top = LL_new(s->ch);
s=s->next;
while(s){
curr = curr->next = LL_new(s->ch);
s=s->next;
}
return top;
}
void LL_println(const LL_str *s){
while(s){
putchar(s->ch);
s = s->next;
}
putchar('\n');
}
void LL_drop(LL_str *s){
if(s){
LL_drop(s->next);
free(s);
}
}
int main(int argc, char *argv[]){
LL_str *s = s_to_LL("Hello world!");
LL_str *d = LL_strcpy(s);
LL_println(d);
LL_drop(s);
LL_drop(d);
return 0;
}
if((NULL != dest_ptr) && (NULL != src_ptr)) --> this is correct
while (NULL != *src_ptr) --> this is wrong.
Please check the data type carefully. Don't mix up variable and pointer-to-variable

can´t find element on a linked list

I have the next code, first i create a list from a file named hc12,and then i search the codop = "BLE" that has to be found on the list, but instead i keep getting the message COULDNT FIND CODOP. i dont know why, the linked list works well.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef struct nodo
{
char *code;
struct nodo *next;
}COD;
COD *createNodo(char *instruction);
void insertEnd(char *instruction,COD *last);
COD *lastElement(COD *head);
void remove(char *c);
void searchEndofLine(FILE *fd);
void ignoreSpaces(FILE *fd);
void CodopsList(COD *head);
char *OperandsTable(FILE *hc12);
COD *searchCodop(COD *head,char *codop);
int main()
{
COD *head = NULL,*found;
char *codop = "BLE";
CodopsList(head);
if((found = searchCodop(head,codop)) == NULL)
printf("COULDNT FIND CODOP");
else
printf("CODOP FOUND");
return 0;
}
void searchEndofLine(FILE *fd)
{
int car;
while((car = fgetc(fd))!= '\n')
;
}
void ignoreSpaces(FILE *fd)
{
int car;
do
{
car = fgetc(fd);
}while(car == '\t' || car == ' ');
}
void remove(char *c)
{
char *ptr;
if(((ptr=strchr(c,'\n'))!=NULL)||((ptr=strchr(c,'\t'))!=NULL)||((ptr=strchr(c,' '))!=NULL))
*ptr = '\0';
}
void CodopsList(COD *head)
{
int car;
FILE *hc12;
char *instruction;
COD *last;
if((hc12 = fopen("TABOP.txt","r"))!= NULL)
{
while((car = fgetc(hc12))!= EOF)
{
if(car != '\t')
{
instruction = OperandsTable(hc12);
if(head == NULL)
head = createNodo(instruction);
else
{
last = lastElement(head);
insertEnd(instruction,last);
}
}
else
searchEndofLine(hc12);
}
}
else
printf("Error\n");
}
char *OperandsTable(FILE *hc12)
{
int car,lon = 0,pos;
char *c;
fseek(hc12,-1,SEEK_CUR);
pos = ftell(hc12);
do
{
car = fgetc(hc12);
lon++;
}while(car != '\t');
fseek(hc12,pos,SEEK_SET);
c = (char*)calloc((lon+1),sizeof(char));
fgets(c,lon+1,hc12);
remove(c);
searchEndofLine(hc12);
return c;
}
void insertEnd(char *instruction,COD *last)
{
last->next = createNodo(instruction);
last->next->next = NULL;
last = last->next;
}
COD *lastElement(COD *head)
{
COD *ptr;
ptr = head;
while(ptr->next != NULL)
ptr = ptr->next;
return ptr;
}
COD *createNodo(char *instruction)
{
COD *x;
int t;
t = strlen(instruction);
x = (COD*)malloc(sizeof(COD));
x->codigo = (char*)malloc((t+1)*sizeof(char));
strcpy(x->code,instruction);
x->next = NULL;
return x;
}
COD *searchCodop(COD *head,char *codop)
{
COD *ptr;
for(ptr = head;ptr != NULL;ptr = ptr->next)
{
if(ptr->code == codop)
return ptr;
}
return NULL;
}
You should use strcmp instead of comparing two array pointers.
In searchCodop instead of
if(ptr->code == codop)
do
if (!strcmp(ptr->code, codop))
You are calling pointer as pass by value, instead use call by reference. For this, use pointer to pointer. Like that:
In main change
CodopsList(head);
with
CodopsList(&head);
And,
Change function
void CodopsList(COD *head)
with
void CodopsList(COD **head)
In function CodopsList use head as *head

Resources