Enter Data in linked-list - c

I need to insert every character of a message into a linked list, but I don't understand where I am going wrong
I'm allocating right, but at the time of printing the message, is giving error
Can someone help me?
As Struct
struct mensagem{
char msg;
char chave;
};
struct elemento{
struct mensagem dados;
struct elemento *prox;
};
typedef struct elemento* Lista;
typedef struct elemento Elem;
The functions- Build list , insert element and print list
Lista* cria_lista(){
Lista* li = (Lista*) malloc(sizeof(Lista));
if(li != NULL)
*li = NULL;
return li;
}
int insere_lista_final(Lista* li, struct mensagem al){
if(li == NULL)
return 0;
Elem *no;
no = (Elem*) malloc(sizeof(Elem));
if(no == NULL)
return 0;
no->dados = al;
no->prox = NULL;
if((*li) == NULL){//lista vazia: insere início
*li = no;
}else{
Elem *aux;
aux = *li;
while(aux->prox != NULL){
aux = aux->prox;
}
aux->prox = no;
}
return 1;
}
void imprime_lista(Lista* li){
if(li == NULL)
return 0;
Elem* no = *li;
while(no != NULL){
printf("%c1",no->dados.msg);
no = no->prox;
}
}
Int main
int main()
{
int mod_exec=1,i=0;
char c;
struct mensagem al;
Lista* li = cria_lista();
while((c = getchar()) != '\n')
{
insere_lista_final(li,al);
imprime_lista(li);
}
return 0 ;
}
typedef struct elemento* Lista;
typedef struct elemento Elem;
Lista* cria_lista(){
Lista* li = (Lista*) malloc(sizeof(Lista));
if(li != NULL)
*li = NULL;
return li;
}
int insere_lista_final(Lista* li, struct mensagem al){
if(li == NULL)
return 0;
Elem *no;
no = (Elem*) malloc(sizeof(Elem));
if(no == NULL)
return 0;
no->dados = al;
no->prox = NULL;
if((*li) == NULL){//lista vazia: insere início
*li = no;
}else{
Elem *aux;
aux = *li;
while(aux->prox != NULL){
aux = aux->prox;
}
aux->prox = no;
}
return 1;
}
void imprime_lista(Lista* li){
if(li == NULL)
return 0;
Elem* no = *li;
while(no != NULL){
printf("%c1",no->dados.msg);
no = no->prox;
}
}
Int main
int main()
{
int mod_exec=1,i=0;
char c;
struct mensagem al;
Lista* li = cria_lista();
while((c = getchar()) != '\n')
{
insere_lista_final(li,al);
imprime_lista(li);
}
return 0 ;
}

Adding a main function with properly initialized variables didn't lead me to errors:
int main(void)
{
Lista *l = cria_lista();
struct mensagem m1 = { .msg = 'a', .chave = 'b'};
struct mensagem m2 = { .msg = 'c', .chave = 'd'};
insere_lista_final(l,m1);
insere_lista_final(l,m2);
imprime_lista(l);
return 0;
}
Be sure your trigger warnings flags when compiling.

Related

Infinite loop when adding 1 character to a list

I am writting a program which adds a character to a list. The problem is that when I have my original list of 5 nodes and I try to add another, everything works, but than when I try to add another one the stampa function becomes infinite.
I can not find the bug. Any help would be welcomed. Here is the code:
struct nodo {
char c;
struct nodo *next;
};
typedef struct nodo *lista;
void mc_coda(lista *l, char el);
void stampa(lista nodo01);
int main() {
int test[5] = {0, 1, 1, 0, 1};
lista nodo01 = malloc(sizeof(struct nodo));
lista nodo02 = malloc(sizeof(struct nodo));
lista nodo03 = malloc(sizeof(struct nodo));
lista nodo04 = malloc(sizeof(struct nodo));
lista nodo05 = malloc(sizeof(struct nodo));
(*nodo01).next = nodo02;
(*nodo02).next = nodo03;
(*nodo03).next = nodo04;
(*nodo04).next = nodo05;
(*nodo05).next = NULL;
(*nodo01).c = 'a';
(*nodo02).c = 'b';
(*nodo03).c = 'c';
(*nodo04).c = 'd';
(*nodo05).c = 'e';
mc_coda(&nodo01, 'e');
mc_coda(&nodo01,
'f'); // If this line is removed everything workd fine, if this line
// if added that it prints infinite f
stampa(nodo01);
return 0;
}
void mc_coda(lista *l, char el) {
if ((*l) == NULL) {
struct nodo temp;
temp.next = NULL;
temp.c = el;
(*l) = &temp;
} else {
while ((*l) != NULL) {
l = &(*(*l)).next;
}
struct nodo temp;
temp.next = NULL;
temp.c = el;
(*l) = &temp;
}
}
void stampa(lista nodo01) {
while (nodo01 != NULL) {
printf("%c\n", (*nodo01).c);
nodo01 = (*nodo01).next;
}
}
Your implementation of mc_coda creates a local variable temp. Because temp is a local variable it will go out of scope when the function exits and then the space will be reused. Instead, you need to allocate space on the heap with malloc. See the below implementation of mc_coda for an example of how to do that:
#include <stdio.h>
#include <stdlib.h>
struct nodo {
char c;
struct nodo *next;
};
typedef struct nodo *lista;
void mc_coda(lista *l, char el);
void stampa(lista nodo01);
int main() {
lista nodo01 = malloc(sizeof(struct nodo));
lista nodo02 = malloc(sizeof(struct nodo));
lista nodo03 = malloc(sizeof(struct nodo));
lista nodo04 = malloc(sizeof(struct nodo));
lista nodo05 = malloc(sizeof(struct nodo));
(*nodo01).next = nodo02;
(*nodo02).next = nodo03;
(*nodo03).next = nodo04;
(*nodo04).next = nodo05;
(*nodo05).next = NULL;
(*nodo01).c = 'a';
(*nodo02).c = 'b';
(*nodo03).c = 'c';
(*nodo04).c = 'd';
(*nodo05).c = 'e';
mc_coda(&nodo01, 'e');
mc_coda(&nodo01, 'f');
stampa(nodo01);
return 0;
}
void mc_coda(lista *l, char el) {
lista tmp = malloc(sizeof(struct nodo));
tmp->next = NULL;
tmp->c = el;
if ((*l) == NULL) {
(*l) = tmp;
} else {
while ((*l) != NULL) {
l = &(*(*l)).next;
}
(*l) = tmp;
}
}
void stampa(lista nodo01) {
while (nodo01 != NULL) {
printf("%c\n", (*nodo01).c);
nodo01 = (*nodo01).next;
}
}

How do I iterate and print hashtable in c?

The implementation uses a structure similar to the "Static Sequence List" (it uses an array to store the elements). I can insert and query 1 item. But I need to list all the items.
The code:
struct cidade {
int pkCidade;
char nomeCidade[50];
};
struct hashCidade {
int qtdCidade, TABLE_SIZE;
struct cidade **itensCidade;
};
typedef struct hashCidade HashCidade;
HashCidade *createHashCidade(int TABLE_SIZE);
void releaseHashCidade(HashCidade *ha);
int insertHashCidade(HashCidade *ha, struct cidade CidadeH);
int findHashCidade(HashCidade *ha, char *str, struct cidade *CidadeH);
HashCidade *createHashCidade(int TABLE_SIZE) {
HashCidade *ha = (HashCidade*)malloc(sizeof(HashCidade));
if (ha != NULL) {
int i;
ha->TABLE_SIZE = TABLE_SIZE;
ha->itensCidade = (struct cidade **)
malloc(TABLE_SIZE * sizeof(struct cidade*));
if (ha->itensCidade == NULL) {
free(ha);
return NULL;
}
ha->qtdCidade = 0;
for (i = 0; i < ha->TABLE_SIZE; i++)
ha->itensCidade[i] = NULL;
}
return ha;
}
void releaseHashCidade(HashCidade *ha) {
if (ha != NULL) {
int i;
for (i = 0; i < ha->TABLE_SIZE; i++) {
if (ha->itensCidade[i] != NULL)
free(ha->itensCidade[i]);
}
free(ha->itensCidade);
free(ha);
}
}
int insertHashCidade(HashCidade *ha, struct cidade CidadeH) {
if (ha == NULL || ha->qtdCidade == ha->TABLE_SIZE)
return 0;
int chave = valorString(CidadeH.nomeCidade);
int pos = chaveDivisao(chave, ha->TABLE_SIZE);
struct cidade *nova;
nova = (struct cidade *)malloc(sizeof(struct cidade));
if(nova == NULL)
return 0;
*nova = CidadeH;
ha->itensCidade[pos] = nova;
ha->qtdCidade++;
return 1;
}
int findHashCidade(HashCidade *ha, char *str, struct cidade *CidadeH) {
if (ha == NULL)
return 'n';
int chave = valorString(str);
int pos = chaveDivisao(chave, ha->TABLE_SIZE);
if (ha->itensCidade[pos] == NULL)
return 0;
else
*CidadeH = *(ha->itensCidade[pos]);
return 1;
}
Thanks for any help.
It seems to me you can just iterate over the non NULL pointers in the hash array and print the corresponding structure details:
void printCidade(const struct cidade *cp) {
printf("%s\n", cp->nomeCidade);
}
void printHashCidade(const HashCidade *ha) {
if (ha != NULL) {
int i;
for (i = 0; i < ha->TABLE_SIZE; i++) {
if (ha->itensCidade[i] != NULL)
printCidade(ha->itensCidade[i]);
}
}
}

Trying to delete all the elements from HashTable with the status marked as closed

#include<iostream>
using namespace std;
enum Stare {DESCHIS=10, LUCRU=20, DUPLICAT=30, REZOLVAT=40, INCHIS=50};
struct Task
{
char *idTask;
char *data;
char *numeInginer;
int nivelComplexitate;
Stare stare;
};
struct List
{
Task *task;
List*next;
};
struct HashTable
{
List** vector;
int size;
};
List* creareNodLista(Task *task)
{
List*nod = (List*)malloc(sizeof(List));
nod->task = task;
nod->next = NULL;
return nod;
}
void initHashTable(HashTable &hTable, int size)
{
hTable.vector = (List**)malloc(sizeof(List*)*size);
hTable.size = size;
memset(hTable.vector, 0, sizeof(List*)*size);
}
int fhash(char c, int l)
{
return c%l;
}
void inserareNodLista(List*&list, List*nod)
{
nod->next = list;
list = nod;
}
void inserareNodHashTable(HashTable hTable, List*nod)
{ //determinarea pozitiei pe care se face inserarea
int index = fhash(nod->task->numeInginer[0],hTable.size);
//obtinerea listei in care se face inserarea
List*list = hTable.vector[index];
//inserare element nou in lista
inserareNodLista(list, nod);
//actualizare element in hashTable
hTable.vector[index] = list;
}
List* getHashTable(HashTable ht, char cheie)
{
int f = fhash(cheie, ht.size);
return ht.vector[f];
}
void printHashTable(HashTable ht)
{
for (char c = 'A'; c < 'Z'; c++)
{
List*lista = getHashTable(ht, c);
int count = 0;
while (lista)
{
count++;
printf("%d", count);
printf("%s\n", lista->task->idTask);
printf("%s\n", lista->task->data);
printf("%s\n", lista->task->numeInginer);
printf("%d\n", lista->task->nivelComplexitate);
printf("%d\n", lista->task->stare);
lista = lista->next;
}
if (count>1)
printf("\nColiziune\n\n");
}
}
int stergeNodHashTable(HashTable hTable, char*numeInginer)
{
int pozitie = 0;
pozitie = fhash(numeInginer[0], hTable.size);
if (hTable.vector[pozitie] == NULL)
return -1;
else
{
if (strcmp(hTable.vector[pozitie]->task->numeInginer, numeInginer) == 0)
{
if (hTable.vector[pozitie]->next == NULL)
{
free(hTable.vector[pozitie]->task->idTask);
free(hTable.vector[pozitie]->task->data);
free(hTable.vector[pozitie]->task->numeInginer);
free(hTable.vector[pozitie]->task);
free(hTable.vector[pozitie]);
hTable.vector[pozitie] = NULL;
}
else
{
List*lista = hTable.vector[pozitie];
hTable.vector[pozitie] = lista->next;
free(lista->task->idTask);
free(lista->task->data);
free(lista->task->numeInginer);
free(lista->task);
free(lista);
lista->next = NULL;
lista = NULL;
}
}
else
{
List*tmp = hTable.vector[pozitie];
while (tmp->next != NULL && strcmp(tmp->next->task->numeInginer, numeInginer) != 0)
tmp = tmp->next;
List*list = tmp->next;
if (list->next == NULL)
{
free(list->task->idTask);
free(list->task->numeInginer);
free(list->task->data);
free(list->task);
free(list);
tmp->next = NULL;
list = NULL;
}
else
{
List*tmp = list;
list = list->next;
free(tmp->task->idTask);
free(tmp->task->data);
free(tmp->task->numeInginer);
free(tmp->task);
free(tmp);
tmp->next = NULL;
tmp = NULL;
}
}
}
return pozitie;
}
void main()
{
FILE *pFile = fopen("Text.txt", "r");
Task *task = NULL;
HashTable ht;
initHashTable(ht, 29);
if (pFile)
{
while (!feof(pFile))
{
task = (Task*)malloc(sizeof(Task));
char id[50];
fscanf(pFile, "%s", &id);
task->idTask = (char*)malloc(strlen(id) + 1);
strcpy(task->idTask, id);
char data[50];
fscanf(pFile, "%s", data);
task->data = (char*)malloc(strlen(data) + 1);
strcpy(task->data, data);
char numeInfiner[50];
fscanf(pFile, "%s", numeInfiner);
task->numeInginer = (char*)malloc(strlen(numeInfiner) + 1);
strcpy(task->numeInginer, numeInfiner);
fscanf(pFile, "%d", &task->nivelComplexitate);
fscanf(pFile, "%d", &task->stare);
//creare element lista
List*nod = creareNodLista(task);
//inserare element in hashTable
inserareNodHashTable(ht, nod);
}
fclose(pFile);
for (char c = 'A'; c < 'Z'; c++)
{
List *lista = getHashTable(ht, c);
while (lista)
{
if (lista->task->stare == 50)
stergeNodHashTable(ht, lista->task->numeInginer);
}
}
printHashTable(ht);
}
}
I am trying to delete from hashTable all the elements with status marked as closed. The delete function is working fine but when i call it for al the hashtable, it got me error: lista->task was 0xDDDDDD. I cant understand why. Please help me!

printing a pointer value

i have this issue while trying to print *p value while p is pointed to a nodo of the list (obviusly i would like to print the nodo.info value)
here is the code, hope u understand:
struct nodo {
int info;
struct nodo *prec;
struct nodo *succ;
} ;
typedef struct nodo nodo;
int main (void) { // just declaring my 3 nodos
struct nodo *p;
struct nodo anodo;
struct nodo bnodo;
struct nodo cnodo;
anodo.info = 200;
anodo.prec = NULL;
anodo.succ = NULL;
bnodo.info = 22;
bnodo.prec = NULL;
bnodo.succ = NULL;
cnodo.info = 2000;
cnodo.prec = NULL;
cnodo.succ = NULL;
anodo.succ = &bnodo;
bnodo.prec = &anodo;
bnodo.succ = &cnodo;
cnodo.prec = &bnodo;
p = &anodo;
printf("\n%d\n", checklist (p)); // calling function
return 0;
}
nodo *checklist (struct nodo *p) {
int j=0;
while (p != NULL) {
if (p->info >= p->succ->info) { //if first element is major or same than next
p=p->succ;
} else {
while (p != NULL) {
if (p->info >= p->succ->info) { //same
p=p->succ;
j++;
} else {
p = NULL;
}
}
}
}
while (j != 0) {
p = p->prec; //used a counter to get back to the first nodo in wich next was less than prev
j--;
}
return p;
}
feel free to ask any details
p = checklist (p);
if (p)
printf("\n%d\n", p->info);
You need to return the nodo.info then
int checklist (struct nodo *p) {
int j=0;
while (p != NULL) {
/* avoid this p->succ->info */
if (p->info >= p->succ->info) { //if first element is major or same than next
p = p->succ;
} else {
while (p != NULL) {
if (p->info >= p->succ->info) { //same
p = p->succ;
j++;
} else {
p = NULL;
}
}
}
}
while (j != 0) { p = p->prec; //used a counter to get back to the first nodo in wich next was less than prev
j--;
}
return p->info;
}
or in main
int info
struct nodo *found;
found = checklist(p);
if (found != NULL)
printf("\n%d\n", found->info);

Sorting Simple Linked List - C

[UPTATED WITH ANSWER AT THE END] I tried many things but I still don't know how I can do any sorting with a simple linked list. It should be sorted like the number saved on each node goes from the lower till the higher one. What can I do?
I'm not allowed to sort the numbers as I save then on the list. The sorting must be made after the list is complete.
the code isn't completely ready yet
#include <stdlib.h>
#include <stdio.h>
#include <math.h>
#include <string.h>
#define pi 3.14159265359
#define N 50
typedef struct lista{
char palavra[N];
int repeticao;
struct lista *prox;
} Lista;
Lista* lista_cria(){
return NULL;
}
int vazia(Lista *LISTA){
if(LISTA->prox == NULL) return 1;
else return 0;
}
void insere(Lista **lis, char *s){
Lista* novo = (Lista*) malloc (sizeof(Lista));
strcpy(novo->palavra, s);
novo->prox = NULL;
while (*lis)
lis = &(*lis)->prox;
*lis = novo;
}
Lista* retira(Lista* lis, char *s){
Lista* ant = NULL;
Lista* p = lis;
while(p != NULL && (strcmp(s, p->palavra) != 0)){
ant = p;
p = p->prox;
}
if(p == NULL) return lis;
if(ant == NULL) lis = p->prox;
else ant->prox = p->prox;
free(p);
return lis;
}
void imprimir_lista(Lista* lis){
Lista* p;
for(p = lis; p != NULL; p = p->prox)
printf("%s ", p->palavra);
printf("\n \n");
}
int busca(Lista* lis, char *s){
Lista *p;
int cont = 0;
for(p = lis; p != NULL; p = p->prox){
if(strcmp(p->palavra, s) == 0) cont++;
}
return cont;
}
Lista* repeticao(Lista* lis, int i){
Lista *p;
char s[50];
int cont;
printf("\n \n Doc%d", i);
for(p = lis; p != NULL; p = p->prox){
strcpy(s, p->palavra);
cont = busca(p, s);
printf(" \n\t %s: %d ", s, cont);
p->repeticao = cont;
}
return lis; /* return p*/
}
void liberar_lista(Lista *lis){
Lista *aux = lis;
while (aux != NULL) {
Lista *aux2 = aux->prox;
free(aux);
aux = aux2;
}
}
float produto_escalar (Lista *lis1, Lista *lis2) {
Lista *aux1 = lis1, *aux2 = lis2;
float resultado=0;
while (aux1 != NULL) {
while (aux2 != NULL) {
if (strcmp(aux1->palavra, aux2->palavra) == 0 ) {
resultado+=(aux1->repeticao*aux2->repeticao);
aux2 = aux2->prox;
break;
}
else {
aux2 = aux2->prox;
}
}
aux1 = aux1->prox;
aux2 = lis2;
}
return resultado;
}
float formula (Lista *lis1, Lista *lis2){
float resultado;
resultado = acos(produto_escalar(lis1, lis2)/(sqrt(produto_escalar(lis1, lis1))*sqrt(produto_escalar(lis2, lis2))));
resultado = (((resultado *50)*4)/pi)-100;
if (resultado<0){
resultado*=-1;
}
return resultado;
}
void checa_plagio (float resultado) {
if (resultado>=50) {
printf("\n O arquivo foi plagiado. \n\t Arquivo é %.3f%% parecido.", resultado);
}
else
printf("\n O arquivo não foi plagiado \n\t Arquivo é %.3f%% parecido.", resultado);
}
int main () {
char arquivo1[] = "doc1.txt", arquivo2[] = "doc2.txt";
char string[50];
double resposta;
FILE *fp1, *fp2;
Lista *lista1, *lista2;
lista1 = lista_cria();
lista2 = lista_cria();
fp1 = fopen (arquivo1, "r+") ;
if (fp1 == NULL) {
printf("\nErro. Não foi possível abrir o arquivo.\n");
return EXIT_FAILURE;
}
while(!feof(fp1)){
fscanf(fp1, "%s[A-Z a-z]", string);
insere(&lista1, string);
}
fclose(fp1);
fp2 = fopen (arquivo2, "r+") ;
if (fp2 == NULL) {
printf("\nErro. Não foi possível abrir o arquivo.\n");
return EXIT_FAILURE;
}
while(!feof(fp2)){
fscanf(fp2, "%s[A-Z a-z]", string);
insere(&lista2, string);
}
fclose(fp2);
/*imprimir_lista(lista1);
imprimir_lista(lista2);*/
lista1 = repeticao(lista1, 1);
lista2 = repeticao(lista2, 2);
resposta = formula (lista1, lista2);
checa_plagio(resposta);
liberar_lista(lista1);
liberar_lista(lista2);
return EXIT_SUCCESS;
}
[UPDATED WITH ANSWER]
THE CODE I USED TO SORT:
#define N 50
#include <stdlib.h>
#include <stdio.h>
typedef struct lista{
char palavra[N];
int repeticao;
struct lista *prox;
} Lista;
Lista* sort (Lista *lis) {
Lista *temp, *empurra;
Lista *aux1, *aux2;
Lista *guarda;
aux1 = NULL;
for (temp = lis; temp != NULL; temp = temp->prox){
aux2 = temp;
for (empurra=temp->prox; empurra != NULL; empurra = empurra->prox){
if (empurra->repeticao < temp->repeticao){
guarda = temp->prox;
temp->prox = empurra->prox;
if(guarda == empurra)
empurra->prox = temp;
else
empurra->prox = guarda;
if(aux2 != temp)
aux2->prox = temp;
if(aux1)
aux1->prox = empurra;
else
lis = empurra;
guarda = temp;
temp = empurra;
empurra = guarda;
}
aux2 = empurra;
}
aux1 = temp;
}
return lis;
}
int main (){
return 0;
}
I think the most learning approach that you can take, it's to think that the linked list is an array. With that approach you can simply, access the elements of the array and apply a sort algorithm (like bubble sort) and when make the swap of the elements using the pointer to the elements. With that would be just a matter to redirect the pointers (to next elements) for the right elements.
Also, pay attention to the particular cases of the sorts (the beginning and the end of list, in this case).
Here's a example:
Suppose that we have the structure for the linked list:
typedef struct list{
int n;
struct list *next;
} List;
And we want to sort the linked list using the int n, a code example would be something like this:
void sort (List * begin) {
List *currentElement, *previousElement;
int swapped = 1;
while (swapped) {
swapped = 1;
while (swapped != 0) {
swapped = 0;
currentElement = begin;
previousElement = NULL; //No previous element in the beginning of the list
while(currentElement->next != NULL) { //Has another element, it's not the end of the list
List *nextElement = currentElement->next;
if(currentElement->n > nextElement->n) {
//swapping the elements
if (previousElement == NULL) { //is the first element
List *auxPtr = nextElement->next;
nextElement->next = currentElement;
currentElement->next = auxPtr;
begin = nextElement; //nextElement is the first element of the list now
}
else {
previousElement->next = nextElement;
currentElement->nextElement->next;
nextElement->next = currentElement;
}
previousElement = nextElement; //The nextElement is 'behind' the currentElement so it should be the previousElement
swapped = 1; // a swap was made
//The elements where swapped so currentElement is already in the 'position' of the next element, there is no need to upload it value
}
else { // there is no need to swap, just walk foward in the list
previousElement = currentElement;
currentElement = nextElement;
}
}
}
}
}
I used a simple bubble sort for the sorting

Resources