#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include "mtll.h"
#define MAX_LISTS 10
#define INT_TYPE 1
#define FLOAT_TYPE 2
#define CHAR_TYPE 3
#define STRING_TYPE 4
struct mtll {
int data_type;
int data_int;
double data_double;
char data_char;
char *data_string;
struct mtll *next;
};
struct mtll empty;
struct mtll *mtll_create() {
struct mtll *new_node = (struct mtll *)malloc(sizeof(struct mtll));
if (new_node == NULL) {
printf("Memory allocation failed.\n");
exit(EXIT_FAILURE);
}
new_node->data_type = 0;
new_node->data_int = 0;
new_node->data_double = 0.0;
new_node->data_char = '\0';
new_node->data_string = NULL;
new_node->next = NULL;
return new_node;
}
void mtll_append(struct mtll **head, struct mtll *new_node) {
if (*head == NULL) {
*head = new_node;
return;
}
struct mtll *temp = *head;
while (temp->next != NULL) {
temp = temp->next;
}
temp->next = new_node;
}
void mtll_view(struct mtll *head) {
if (head == NULL || head == &empty) {
if (head == NULL) {
printf("INVALID COMMAND: VIEW");
}
printf("\n");
return;
}
if (head->data_type == INT_TYPE) {
printf("%d", head->data_int);
} else if (head->data_type == FLOAT_TYPE) {
printf("%.2f", head->data_double);
} else if (head->data_type == CHAR_TYPE) {
printf("%c", head->data_char);
} else if (head->data_type == STRING_TYPE) {
printf("%s", head->data_string);
}
head = head->next;
while (head != NULL) {
if (head->data_type == INT_TYPE) {
printf(" -> %d", head->data_int);
} else if (head->data_type == FLOAT_TYPE) {
printf(" -> %.2f", head->data_double);
} else if (head->data_type == CHAR_TYPE) {
printf(" -> %c", head->data_char);
} else if (head->data_type == STRING_TYPE) {
printf(" -> %s", head->data_string);
}
head = head->next;
}
printf("\n");
}
void mtll_free(struct mtll *head) {
struct mtll *current = head;
if (current == NULL || current == &empty) {
return;
}
while (current != NULL) {
struct mtll *temp = current;
current = current->next;
if (temp->data_type == STRING_TYPE && temp->data_string != NULL) {
free(temp->data_string);
}
free(temp);
}
}
void mtll_new(int num_elements, struct mtll **lists, int *list_count) {
struct mtll *list = NULL;
char data[150];
int type_invalid = 0;
for (int i = 0; i < num_elements; i++) {
if (fgets(data, sizeof(data), stdin) != NULL) {
if (type_invalid) {
continue;
};
struct mtll *new_node = mtll_create();
if (new_node == NULL) {
printf("Memory allocation failed.\n");
exit(EXIT_FAILURE);
}
// Remove trailing newline character if present
size_t len = strlen(data);
if (len > 0 && data[len - 1] == '\n') {
data[len - 1] = '\0';
}
// If the line is empty, treat it as a string element
if (strcmp(data, "") == 0) {
new_node->data_type = STRING_TYPE;
new_node->data_string = (char *)malloc(1);
if (new_node->data_string == NULL) {
printf("Memory allocation failed.\n");
exit(EXIT_FAILURE);
}
new_node->data_string[0] = '\0';
} else {
// only contain digit or '-'
int type_int = 1;
for (int j = 0; j < strlen(data); j++) {
if (!isdigit(data[j]) && data[j] != '-') {
type_int = 0;
break;
}
}
if (type_int) {
new_node->data_type = INT_TYPE;
new_node->data_int = atoi(data);
} else {
// only contain digit or '-' or '.' or 'e'
int type_float = 1;
for (int j = 0; j < strlen(data); j++) {
if (!isdigit(data[j]) && data[j] != '.' && data[j] != '-' && data[j] != 'e') {
type_float = 0;
break;
}
if (isdigit(data[j])) {
type_float += 1;
}
}
if (type_float > 1) {
new_node->data_type = FLOAT_TYPE;
new_node->data_double = atof(data);
} else {
if (strlen(data) == 1 && isprint(data[0])) {
new_node->data_type = CHAR_TYPE;
new_node->data_char = data[0];
} else {
new_node->data_type = STRING_TYPE;
new_node->data_string = (char *)malloc(strlen(data) + 1);
for (int j = 0; j < strlen(data); j++) {
if (data[j] == '{' || data[j] == '}') {
type_invalid = 1;
break;
}
}
if (new_node->data_string == NULL) {
printf("Memory allocation failed.\n");
exit(EXIT_FAILURE);
}
strcpy(new_node->data_string, data);
}
}
}
}
if (type_invalid) {
mtll_free(list);
mtll_free(new_node);
} else {
mtll_append(&list, new_node);
}
} else {
mtll_free(list);
return;
}
}
if (type_invalid) {
printf("INVALID COMMAND: NEW\n");
return;
}
printf("List %d: ", *list_count);
if (list == NULL) {
list = ∅
}
mtll_view(list);
lists[*list_count] = list;
*list_count = *list_count + 1;
// Return to terminate the function
return;
}
void mtll_view_all(struct mtll **lists, int list_count) {
int count = 0;
for (int i = 0; i < list_count; i++) {
if (lists[i] != NULL) {
count++;
}
}
printf("Number of lists: %d\n", count);
for (int i = 0; i < list_count; i++) {
if (lists[i] != NULL) {
printf("List %d\n", i);
}
}
}
// Function to print the types of elements in the linked list
void mtll_type(struct mtll *head) {
if (head == NULL || head == &empty) {
printf("\n");
return;
}
while (head != NULL) {
if (head->data_type == INT_TYPE) {
printf("int");
} else if (head->data_type == FLOAT_TYPE) {
printf("float");
} else if (head->data_type == CHAR_TYPE) {
printf("char");
} else if (head->data_type == STRING_TYPE) {
printf("string");
}
head = head->next;
if (head != NULL)
printf(" -> ");
}
printf("\n");
}
// Function to get the length of a list
int mtll_length(struct mtll *head) {
int length = 0;
if (head == NULL || head == &empty) {
return length;
}
while (head != NULL) {
length++;
head = head->next;
}
return length;
}
// Function to insert a value into the specified index of a list
void mtll_insert(struct mtll **head, int list_id, int index, char *data) {
int length = mtll_length(*head);
if (index < 0) {
index = length + index + 1;
}
int type_inval