online compiler and debugger for c/c++

code. compile. run. debug. share.
Source Code   
Language
/* * EXPLICAÇÃO DETALHADA DO PROGRAMA * Este programa implementa um Gerenciador de Lista de Compras utilizando uma * **Lista Duplamente Encadeada** (Doubly Linked List). * * DIFERENÇAS PARA A LISTA ESTÁTICA: * - Memória Dinâmica: Os itens são alocados em tempo de execução (malloc), * permitindo um número teoricamente ilimitado de itens (até a memória acabar). * - Eficiência: A inserção e remoção são eficientes pois não exigem deslocar * todos os outros elementos (como em arrays), apenas ajustar os ponteiros. * - Dupla Ligação: Cada nó possui ponteiros para o próximo (`next`) e para o * anterior (`previous`), permitindo navegação em ambas as direções. * * FUNCIONALIDADES: * 1. Inserção (I): Insere produtos mantendo a ordem alfabética. Ajusta os * ponteiros `next` e `previous` dos vizinhos para manter a integridade da lista. * 2. Impressão (P): * - 'F': Imprime do início (head) até o fim (tail). * - 'R': Imprime do fim (tail) até o início (head), facilitando visualizar * os últimos itens adicionados sem percorrer toda a lista. * 3. Atualização (A): Marca um item como comprado. * 4. Exclusão (X): Remove um item e libera a memória corretamente, ajustando * os ponteiros dos nós vizinhos e os ponteiros `head` ou `tail` da lista se necessário. */ #include <stdio.h> #include <stdlib.h> #include <string.h> #define TRUE 1 #define FALSE 0 #define MEMORY_ERROR 2 #define EXEC_SUCCESS 0 // Estrutura do Nó da Lista Duplamente Encadeada struct ListNode { char *productName; // Ponteiro para string dinâmica (nome do produto) float quantity; // Quantidade do item int isBought; // Flag (0=não, 1=sim) indicando se foi comprado struct ListNode *next; // Ponteiro para o próximo nó struct ListNode *previous; // Ponteiro para o nó anterior }; typedef struct ListNode TItem; // Descritor da Lista Duplamente Encadeada typedef struct { TItem *head; // Ponteiro para o início da lista TItem *tail; // Ponteiro para o final da lista int count; // Contador total de itens int boughtCount; // Contador de itens comprados } TList; // Protótipos das funções int UpdateItem(TList *, char []); int DeleteItem(TList *, char []); int InsertItem(TList *, char [], float ); void PrintListForward(TList *); void PrintListReverse(TList *); void InitializeList(TList *); int main(void) { TList list; char operation = '.'; char productName[25]; float productQuantity; TItem *aux; // Inicializa a lista vazia InitializeList(&list); // Loop principal de comandos até o operador '*' while(operation != '*') { scanf(" %c", &operation); if(operation != '*') { scanf("%24s", productName); // Se for inclusão, lê a quantidade também if(operation == 'I') scanf("%f", &productQuantity); } switch(operation) { case 'I': // Insere o novo item e imprime confirmação InsertItem(&list, productName, productQuantity); printf("Incluiu %s \n", productName); productQuantity = 0; break; case 'P': // Verifica o argumento para definir o sentido da impressão if(strcmp("R", productName) == 0) PrintListReverse(&list); else if(strcmp("F", productName) == 0) PrintListForward(&list); break; case 'A': // Marca o item como comprado se existir if(UpdateItem(&list, productName)) printf("Comprou %s \n", productName); break; case 'X': // Remove o item da lista if (DeleteItem(&list, productName)) printf("Excluiu %s\n", productName); break; case '*': // Exibe resumo final e encerra printf("Fim do programa ( %d itens sem comprar)\n", list.count - list.boughtCount); break; default: printf("Operacao invalida.\n"); } } return EXEC_SUCCESS; } // Inicializa os ponteiros e contadores da lista void InitializeList(TList *list) { list->head = NULL; list->tail = NULL; list->count = 0; list->boughtCount = 0; } // Função para inserir um novo item mantendo a ordem alfabética (Inserção Ordenada) int InsertItem(TList *list, char productName[], float quantity) { TItem *newNode, *previousNode, *currentNode; // Aloca memória para o novo nó newNode = (TItem *) malloc(sizeof(TItem)); if (newNode == NULL){ puts("Erro fatal: Memoria insuficiente para esta operacao"); return MEMORY_ERROR; } // Aloca e copia a string do nome (strdup faz malloc + strcpy) newNode->productName = strdup(productName); newNode->quantity = quantity; newNode->isBought = 0; list->count++; // Caso 1: Lista Vazia -> O novo nó é o head e o tail if (list->head == NULL) { list->head = newNode; list->tail = newNode; newNode->previous = NULL; newNode->next = NULL; } else { // Percorre a lista para encontrar a posição alfabética correta previousNode = NULL; currentNode = list->head; while (currentNode != NULL && strcmp(currentNode->productName, productName) < 0) { previousNode = currentNode; currentNode = currentNode->next; } // Caso 2: Inserção no Meio ou Início if (currentNode != NULL) { // Subcaso 2a: Inserção no Início (antes do head atual) if (previousNode == NULL) { list->head = newNode; currentNode->previous = newNode; newNode->next = currentNode; newNode->previous = NULL; } // Subcaso 2b: Inserção no Meio (entre previousNode e currentNode) else { currentNode->previous = newNode; previousNode->next = newNode; newNode->next = currentNode; newNode->previous = previousNode; } } // Caso 3: Inserção no Final (currentNode chegou ao fim/NULL) else { list->tail->next = newNode; newNode->previous = list->tail; list->tail = newNode; newNode->next = NULL; } } return TRUE; } // Marca um item como comprado int UpdateItem(TList *list, char productName[]) { TItem *currentNode, *previousNode; previousNode = NULL; currentNode = list->head; // Busca linear pelo produto while (currentNode != NULL && strcmp(currentNode->productName, productName) != 0) { previousNode = currentNode; currentNode = currentNode->next; } // Se não encontrou if (currentNode == NULL) { printf("Produto '%s' nao encontrado\n", productName); return FALSE; } // Se já foi comprado if (currentNode->isBought == 1) { printf(" %s ja foi comprado \n ", productName); return FALSE; } else { // Marca e atualiza o contador list->boughtCount = list->boughtCount + 1; currentNode->isBought = 1; } return TRUE; } // Imprime a lista do início (head) para o fim (tail) - Ordem Alfabética void PrintListForward(TList *list) { TItem *currentNode; if (list->head == NULL) puts("Lista vazia"); else { printf("\n Lista de compras (do inicio) \n"); currentNode = list->head; while (currentNode != NULL) { printf("%s %.2f %d \n", currentNode->productName, currentNode->quantity, currentNode->isBought); currentNode = currentNode->next; } printf("Total itens: %d Itens comprados: %d\n\n", list->count, list->boughtCount); } } // Imprime a lista do fim (tail) para o início (head) - Ordem Reversa void PrintListReverse(TList *list) { TItem *currentNode; if (list->head == NULL) puts("Lista vazia"); else { printf("\n Lista de compras (do final) \n"); currentNode = list->tail; // Começa pelo final while (currentNode != NULL) { printf("%s %.2f %d \n", currentNode->productName, currentNode->quantity, currentNode->isBought); currentNode = currentNode->previous; // Anda para trás usando o ponteiro previous } printf("Total itens: %d | Itens comprados: %d\n\n", list->count, list->boughtCount); } } // Remove um item da lista e ajusta os ponteiros da lista duplamente encadeada int DeleteItem(TList *list, char productName[]) { TItem *currentNode, *previousNode; previousNode = NULL; currentNode = list->head; // Busca o item a ser removido while (currentNode != NULL && strcmp(currentNode->productName, productName) != 0) { previousNode = currentNode; currentNode = currentNode->next; } // Se não encontrou if (currentNode == NULL){ printf("Valor informado nao existe na lista\n"); return FALSE; } else { // Ajuste dos ponteiros vizinhos para remover o nó // Caso 1: Remoção do Início if (previousNode == NULL) { list->head = currentNode->next; if(list->head != NULL) currentNode->next->previous = NULL; } // Caso 2: Remoção do Meio ou Fim else { previousNode->next = currentNode->next; // Se não é o último item, ajusta o ponteiro 'previous' do próximo if(currentNode->next != NULL) { currentNode->next->previous = previousNode; } } // Atualiza contadores list->count = list->count - 1; if (currentNode->isBought == 1) list->boughtCount--; // Se o item removido era o último, atualiza o ponteiro tail if (currentNode == list->tail) list->tail = previousNode; // Libera a memória do nó e da string do nome free(currentNode->productName); free(currentNode); } return TRUE; }

Compiling Program...

Command line arguments:
Standard Input: Interactive Console Text
×

                

                

Program is not being debugged. Click "Debug" button to start program in debug mode.

#FunctionFile:Line
VariableValue
RegisterValue
ExpressionValue