I created an iterator on my hashTables to help on encapsulating the code.However, on some functions, it just didn't work.For example, on "query3" after I apllied the changes, it worked just fine.
void query3(bool formatFlag, char *args, int commandLineNum, ReservationHashTable* reservationTable) {
char outputFileName[1024];
sprintf(outputFileName, "Resultados/command%d_output.txt", commandLineNum);
FILE* outputFile = fopen(outputFileName, "w");
if (!outputFile) {
perror("Erro ao abrir o arquivo de saída");
return;
}
if (args == NULL || reservationTable == NULL) {
return;
}
char *hotelId = trim(args);
double totalRating = 0.0;
int numRatings = 0;
ReservationIterator *iterador = initReservationIterator(reservationTable);
if (iterador == NULL) {
return;
}
Reservation *reserva;
while ((reserva = getNextReservation(iterador)) != NULL) {
const char* reservationHotelId = getReservationHotelId(reserva);
int reservationRate = getReservationRate(reserva);
if (reservationHotelId != NULL && strcmp(reservationHotelId, hotelId) == 0) {
totalRating += reservationRate;
numRatings++;
}
}
double averageRating = (numRatings > 0) ? totalRating / numRatings : 0.0;
if (formatFlag) {
fprintf(outputFile, "--- 1 ---\n");
fprintf(outputFile, "rating: %.3lf\n", averageRating);
} else {
fprintf(outputFile, "%.3lf\n", averageRating);
}
fclose(outputFile);
}
but on "query4" it stopped working
old query4:
int compareReservations(const void *a, const void *b) {
const Reservation *resA = *(const Reservation **)a;
const Reservation *resB = *(const Reservation **)b;
int dateCompare = strcmp(getReservationDataIni(resA), getReservationDataIni(resB));
if (dateCompare == 0) {
// Usar strcmp para comparar os IDs corretamente
return strcmp(getReservationId(resA), getReservationId(resB));
}
return -dateCompare; // Negativo para ordem decrescente
}
void query4(bool formatFlag, char *args, int commandLineNum, const ReservationHashTable *reservationHashTable) {
if (args == NULL || reservationHashTable == NULL) {
printf("Argumentos inválidos para a query4\n");
return;
}
int conta = 1;
char* hotelId = trim(args);
int n_reservas = getReservationTableCount(reservationHashTable);
int numFiltradas = 0;
Reservation **reservasFiltradas = malloc(n_reservas* sizeof(Reservation*));
if (reservasFiltradas == NULL) {
return;
}
for (int i = 0; i < getReservationTableSize(reservationHashTable); i++) {
ReservationHashNode *node = getReservationTableBucket(reservationHashTable, i);
while (node != NULL) {
Reservation *reservation = getReservationFromNode(node);
if (strcasecmp(getReservationHotelId(reservation), hotelId) == 0) {
if (numFiltradas == n_reservas) {
n_reservas *= 2;
reservasFiltradas = realloc(reservasFiltradas, n_reservas * sizeof(Reservation*));
if (reservasFiltradas == NULL) {
return;
}
}
reservasFiltradas[numFiltradas++] = reservation;
}
node = getNextReservationHashNode(node); // obter o próximo nó
}
}
qsort(reservasFiltradas, numFiltradas, sizeof(Reservation*), compareReservations);
char outputFileName[1024];
sprintf(outputFileName, "Resultados/command%d_output.txt", commandLineNum);
FILE *outputFile = fopen(outputFileName, "w");
if (!outputFile) {
perror("Erro ao abrir o arquivo de saída");
free(reservasFiltradas);
return;
}
for (int i = 0; i < numFiltradas; i++) {
Reservation *reservation = reservasFiltradas[i];
double totalPrice = calcularPrecoTotal(getReservationPrice(reservation),
getReservationTax(reservation),
getReservationDataIni(reservation),
getReservationDataFim(reservation));
if (formatFlag){
fprintf(outputFile, "--- %d ---\n", conta);
fprintf(outputFile, "id: %s\n", getReservationId(reservation));
fprintf(outputFile, "begin_date: %s\n", getReservationDataIni(reservation));
fprintf(outputFile, "end_date: %s\n", getReservationDataFim(reservation));
fprintf(outputFile, "user_id: %s\n", getReservationUserId(reservation));
fprintf(outputFile, "rating: %d\n", getReservationRate(reservation));
fprintf(outputFile, "total_price: %.3lf\n", totalPrice);
if(i<numFiltradas-1) fprintf(outputFile,"\n");
conta++;
}
else {
fprintf(outputFile, "%s;%s;%s;%s;%d;%.3lf\n",
getReservationId(reservation),
getReservationDataIni(reservation),
getReservationDataFim(reservation),
getReservationUserId(reservation),
getReservationRate(reservation),
totalPrice);
}
}
fclose(outputFile);
free(reservasFiltradas);
}
new query4:
#include "query4.h"
// Assumindo que as funções mencionadas e estruturas de dados estão definidas.
// Função auxiliar para comparar datas (e IDs como desempate)
int compareReservations(const void *a, const void *b) {
const Reservation *resA = *(const Reservation **)a;
const Reservation *resB = *(const Reservation **)b;
int dateCompare = strcmp(getReservationDataIni(resA), getReservationDataIni(resB));
if (dateCompare == 0) {
// Usar strcmp para comparar os IDs corretamente
return strcmp(getReservationId(resA), getReservationId(resB));
}
return -dateCompare; // Negativo para ordem decrescente
}
void query4(bool formatFlag, char *args, int commandLineNum, ReservationHashTable *reservationHashTable) {
if (args == NULL || reservationHashTable == NULL) {
printf("Argumentos inválidos para a query4\n");
return;
}
int conta = 1;
char* hotelId = trim(args);
int n_reservas = getReservationTableCount(reservationHashTable);
int numFiltradas = 0;
char outputFileName[1024];
sprintf(outputFileName, "Resultados/command%d_output.txt", commandLineNum);
FILE *outputFile = fopen(outputFileName, "w");
if (!outputFile) {
perror("Erro ao abrir o arquivo de saída");
return;
}
Reservation **reservasFiltradas = malloc(n_reservas* sizeof(Reservation*));
if (reservasFiltradas == NULL) {
return;
}
ReservationIterator *iterador = initReservationIterator(reservationHashTable);
if (iterador == NULL) {
return;
}
Reservation *reserva;
while ((reserva = getNextReservation(iterador)) != NULL) {
if (strcasecmp(getReservationHotelId(reserva), hotelId) == 0) {
if (numFiltradas == n_reservas) {
n_reservas *= 2;
reservasFiltradas = realloc(reservasFiltradas, n_reservas * sizeof(Reservation*));
if (reservasFiltradas == NULL) {
return;
}
reservasFiltradas[numFiltradas++] = reserva;
}
}
}
qsort(reservasFiltradas, numFiltradas, sizeof(Reservation*), compareReservations);
for (int i = 0; i < numFiltradas; i++) {
Reservation *reservation = reservasFiltradas[i];
double totalPrice = calcularPrecoTotal(getReservationPrice(reservation),
getReservationTax(reservation),
getReservationDataIni(reservation),
getReservationDataFim(reservation));
if (formatFlag){
fprintf(outputFile, "--- %d ---\n", conta);
fprintf(outputFile, "id: %s\n", getReservationId(reservation));
fprintf(outputFile, "begin_date: %s\n", getReservationDataIni(reservation));
fprintf(outputFile, "end_date: %s\n", getReservationDataFim(reservation));
fprintf(outputFile, "user_id: %s\n", getReservationUserId(reservation));
fprintf(outputFile, "rating: %d\n", getReservationRate(reservation));
fprintf(outputFile, "total_price: %.3lf\n", totalPrice);
if(i<numFiltradas-1) fprintf(outputFile,"\n");
conta++;
}
else {
fprintf(outputFile, "%s;%s;%s;%s;%d;%.3lf\n",
getReservationId(reservation),
getReservationDataIni(reservation),
getReservationDataFim(reservation),
getReservationUserId(reservation),
getReservationRate(reservation),
totalPrice);
}
}
fclose(outputFile);
free(reservasFiltradas);
}
Iterator:
ReservationIterator *initReservationIterator(ReservationHashTable *table) {
ReservationIterator *iterator = malloc(sizeof(ReservationIterator));
if (iterator != NULL) {
iterator->table = table;
iterator->currentBucket = -1;
iterator->currentNode = NULL;
}
return iterator;
}
Reservation *getNextReservation(ReservationIterator *iterator) {
// Se o iterador já está no final, retorne NULL
if (iterator->currentBucket >= iterator->table->size) {
return NULL;
}
// Avançar para o próximo nó ou bucket, se necessário
if (iterator->currentNode == NULL || iterator->currentNode->next == NULL) {
do {
iterator->currentBucket++;
if (iterator->currentBucket >= iterator->table->size) {
return NULL; // Chegou ao final da tabela
}
iterator->currentNode = iterator->table->buckets[iterator->currentBucket];
} while (iterator->currentNode == NULL);
} else {
iterator->currentNode = iterator->currentNode->next;
}
if (iterator->currentNode != NULL) {
return iterator->currentNode->reservation;
}
return NULL; // Se chegar aqui, não há mais voos
}
some structs that might help:
struct ReservationHashTable {
ReservationHashNode **buckets;
int size;
int count;
};
struct ReservationHashNode {
Reservation *reservation;
struct ReservationHashNode *next;
};
struct ReservationIterator {
ReservationHashTable *table;
int currentBucket;
ReservationHashNode *currentNode;
};
struct Reservation {
char* id;
char* user_id;
char* hotel_id;
char* hotel_name;
int hotel_stars;
int city_tax;
char* address;
char* begin_date;
char* end_date;
int price;
char* breakfast;
char* room_details;
int rate;
char* comment;
};
I tried to do some changes on the code but I really need this iterator to work to keep my code encapsulated.
Also, If anyone of you has another idea of something that I can use instead of the iterator but that could also keep my code encapsulated and would be willing to help me, I would be really gratefull.
Can anyone help me out please? Thanks in advance