ok just a basic version of fb_chatbot_danny converted to C...
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <time.h>
#include <stdbool.h>
#include <unistd.h>
#define MAX_STRING_LENGTH 1000
#define MAX_ARRAY_SIZE 1000
#define MAX_KEYWORDS 20
#define MAX_REPLIES 50
#define MAX_MATCHES 5
#define MAX_SWAP_WORDS 100
#define MAX_MEMORY 10
char wordIn[MAX_SWAP_WORDS][MAX_STRING_LENGTH];
char wordOut[MAX_SWAP_WORDS][MAX_STRING_LENGTH];
int wCnt = 0;
char memory[MAX_MEMORY][MAX_STRING_LENGTH];
int memoryCount = 0;
typedef struct {
char keywords[MAX_KEYWORDS][MAX_STRING_LENGTH];
char replies[MAX_REPLIES][MAX_STRING_LENGTH];
int keywordCount;
int replyCount;
} ArraySet;
ArraySet g_Key_Reply[MAX_ARRAY_SIZE];
int g_Key_ReplyCount = 0;
char default_replies[MAX_ARRAY_SIZE][MAX_STRING_LENGTH];
int default_reply_count = 0;
char* safe_strdup(const char* s) {
if (!s) return NULL;
char* result = strdup(s);
if (!result) {
fprintf(stderr, "Memory allocation failed in safe_strdup\n");
exit(1);
}
return result;
}
char* isolatePunctuation(const char* s) {
char* b = malloc(strlen(s) * 3 + 1);
if (!b) return NULL;
int j = 0;
for (int i = 0; s[i]; i++) {
if (strchr("?!,.:;<>(){}[]", s[i])) {
b[j++] = ' ';
b[j++] = s[i];
b[j++] = ' ';
} else {
b[j++] = s[i];
}
}
b[j] = '\0';
return b;
}
void loadArrays(const char* filename) {
FILE* file = fopen(filename, "r");
if (!file) {
printf("Error opening file: %s\n", filename);
return;
}
char line[MAX_STRING_LENGTH];
int currentSet = -1;
while (fgets(line, sizeof(line), file)) {
line[strcspn(line, "\n")] = 0; // Remove newline
if (strncmp(line, "d1:", 3) == 0) {
strcpy(default_replies[default_reply_count++], line + 3);
}
if (line[0] == 'k' && line[1] == ':') {
if (currentSet == -1 || g_Key_Reply[currentSet].replyCount > 0) {
currentSet++;
}
strcpy(g_Key_Reply[currentSet].keywords[g_Key_Reply[currentSet].keywordCount], line + 2);
g_Key_Reply[currentSet].keywordCount++;
g_Key_ReplyCount = currentSet + 1;
} else if (line[0] == 'r' && line[1] == ':') {
strcpy(g_Key_Reply[currentSet].replies[g_Key_Reply[currentSet].replyCount], line + 2);
g_Key_Reply[currentSet].replyCount++;
}
}
fclose(file);
}
void loadSwapWords(const char* filename) {
FILE* file = fopen(filename, "r");
if (!file) {
printf("Error opening swap words file: %s\n", filename);
return;
}
char line[MAX_STRING_LENGTH];
while (fgets(line, sizeof(line), file) && wCnt < MAX_SWAP_WORDS) {
line[strcspn(line, "\n")] = 0; // Remove newline
if (line[0] == 's' && line[1] == ':') {
char* delimiter = strchr(line + 2, '>');
if (delimiter) {
*delimiter = '\0';
strcpy(wordIn[wCnt], line + 2);
strcpy(wordOut[wCnt], delimiter + 1);
wCnt++;
}
}
}
fclose(file);
}
char* swapWords(const char* input) {
if (!input) return NULL;
char* result = safe_strdup(input);
char* temp = malloc(strlen(input) * 2 + 1); // Allocate more space for worst-case scenario
if (!temp) {
free(result);
return NULL;
}
char* word = strtok(result, " ");
temp[0] = '\0';
while (word != NULL) {
bool swapped = false;
for (int i = 0; i < wCnt; i++) {
if (strcmp(word, wordIn[i]) == 0) {
strcat(temp, wordOut[i]);
strcat(temp, " ");
swapped = true;
break;
}
}
if (!swapped) {
strcat(temp, word);
strcat(temp, " ");
}
word = strtok(NULL, " ");
}
// Remove trailing space
int len = strlen(temp);
if (len > 0 && temp[len - 1] == ' ') {
temp[len - 1] = '\0';
}
free(result);
return temp;
}
char* processReply(const char* reply, const char* userInput) {
if (!reply || !userInput) return NULL;
char* processedReply = safe_strdup(reply);
int len = strlen(processedReply);
if (len > 0 && processedReply[len - 1] == '*') {
processedReply[len - 1] = '\0'; // Remove the asterisk
// Save the user's input to memory
if (memoryCount < MAX_MEMORY) {
strncpy(memory[memoryCount], userInput, MAX_STRING_LENGTH - 1);
memory[memoryCount][MAX_STRING_LENGTH - 1] = '\0';
memoryCount++;
}
// Find the keyword in the user's input
char* keyword = NULL;
for (int i = 0; i < g_Key_ReplyCount; i++) {
for (int j = 0; j < g_Key_Reply[i].keywordCount; j++) {
if (strstr(userInput, g_Key_Reply[i].keywords[j])) {
keyword = g_Key_Reply[i].keywords[j];
break;
}
}
if (keyword) break;
}
if (keyword) {
char* rest = strstr(userInput, keyword);
if (rest) {
rest += strlen(keyword);
char* swapped = swapWords(rest);
if (swapped) {
// Concatenate the swapped input to the reply
char* temp = malloc(strlen(processedReply) + strlen(swapped) + 2);
if (temp) {
sprintf(temp, "%s %s", processedReply, swapped);
free(processedReply);
processedReply = temp;
}
free(swapped);
}
}
}
}
return processedReply;
}
char* userQuestion(const char* txt) {
if (!txt) return NULL;
char* matchedReplies[MAX_MATCHES] = {NULL};
int matchCount = 0;
bool found = false;
char* combinedReply = NULL;
for (int i = 0; i < g_Key_ReplyCount && matchCount < MAX_MATCHES; i++) {
for (int j = 0; j < g_Key_Reply[i].keywordCount; j++) {
if (strstr(txt, g_Key_Reply[i].keywords[j])) {
int replyIndex = rand() % g_Key_Reply[i].replyCount;
matchedReplies[matchCount] = safe_strdup(g_Key_Reply[i].replies[replyIndex]);
matchCount++;
found = true;
break;
}
}
}
if (matchCount > 0) {
size_t totalLength = 1; // Start with 1 for the null terminator
for (int i = 0; i < matchCount; i++) {
char* processedReply = processReply(matchedReplies[i], txt);
if (processedReply) {
totalLength += strlen(processedReply) + 1; // +1 for newline
free(matchedReplies[i]);
matchedReplies[i] = processedReply;
}
}
combinedReply = malloc(totalLength);
if (combinedReply) {
combinedReply[0] = '\0';
for (int i = 0; i < matchCount; i++) {
if (matchedReplies[i]) {
strcat(combinedReply, matchedReplies[i]);
strcat(combinedReply, "\n");
free(matchedReplies[i]);
}
}
}
} else if (!found) {
if (default_reply_count > 0) {
int defaultIndex = rand() % default_reply_count;
combinedReply = safe_strdup(default_replies[defaultIndex]);
}
}
return combinedReply ? combinedReply : safe_strdup("I don't understand. Can you rephrase that?");
}
char* commands(char* txt) {
char* isolated = isolatePunctuation(txt);
for (int i = 0; isolated[i]; i++) {
isolated[i] = tolower(isolated[i]);
}
char* response = userQuestion(isolated);
free(isolated);
return response;
}
void speak(const char* text) {
char command[MAX_STRING_LENGTH * 2];
snprintf(command, sizeof(command), "voice -r -1 -n \"Microsoft David Desktop\" \"%s\"", text);
system(command);
}
int main() {
srand(time(NULL));
loadArrays("database.txt");
loadSwapWords("swapwords.txt");
char input[MAX_STRING_LENGTH];
char* response;
while (1) {
printf("> ");
if (fgets(input, sizeof(input), stdin) == NULL) {
break;
}
input[strcspn(input, "\n")] = 0; // Remove newline
if (strcmp(input, "quit") == 0) break;
response = commands(input);
if (response) {
// Split the response into separate lines and speak each one
char* line = strtok(response, "\n");
while (line != NULL) {
printf("%s\n", line);
speak(line);
line = strtok(NULL, "\n");
}
free(response);
} else {
printf("An error occurred while processing your input.\n");
}
}
return 0;
}
databases files:
swapwords.txt
this chatbot uses voice.exe TTS cli engine
Okay, I made some final adjustments to the chatbot. First, let me clear that this chatbot is not politically correct. It is an offensive chatbot that is not suitable for minors under 18 years old, and also, I do not take on any responsibility for your usage of it. So here are the final elements of almost the final diversion of the chatbot in C programming Language.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <time.h>
#include <stdbool.h>
#include <unistd.h>
#define MAX_STRING_LENGTH 1000
#define MAX_ARRAY_SIZE 1000
#define MAX_KEYWORDS 20
#define MAX_REPLIES 50
#define MAX_MATCHES 10
#define MAX_SWAP_WORDS 100
#define MAX_MEMORY 15
char wordIn[MAX_SWAP_WORDS][MAX_STRING_LENGTH];
char wordOut[MAX_SWAP_WORDS][MAX_STRING_LENGTH];
int wCnt = 0;
char memory[MAX_MEMORY][MAX_STRING_LENGTH];
int memoryCount = 0;
typedef struct {
char keywords[MAX_KEYWORDS][MAX_STRING_LENGTH];
char replies[MAX_REPLIES][MAX_STRING_LENGTH];
int keywordCount;
int replyCount;
} ArraySet;
ArraySet g_Key_Reply[MAX_ARRAY_SIZE];
int g_Key_ReplyCount = 0;
char default_replies[MAX_ARRAY_SIZE][MAX_STRING_LENGTH];
int default_reply_count = 0;
char* safe_strdup(const char* s) {
if (!s) return NULL;
char* result = strdup(s);
if (!result) {
fprintf(stderr, "Memory allocation failed in safe_strdup\n");
exit(1);
}
return result;
}
char* isolatePunctuation(const char* s) {
char* b = malloc(strlen(s) * 3 + 1);
if (!b) return NULL;
int j = 0;
for (int i = 0; s[i]; i++) {
if (strchr("?!,.:;<>(){}[]", s[i])) {
b[j++] = ' ';
b[j++] = s[i];
b[j++] = ' ';
} else {
b[j++] = s[i];
}
}
b[j] = '\0';
return b;
}
void loadArrays(const char* filename) {
FILE* file = fopen(filename, "r");
if (!file) {
printf("Error opening file: %s\n", filename);
return;
}
char line[MAX_STRING_LENGTH];
int currentSet = -1;
while (fgets(line, sizeof(line), file)) {
line[strcspn(line, "\n")] = 0; // Remove newline
if (strncmp(line, "d1:", 3) == 0) {
strcpy(default_replies[default_reply_count++], line + 3);
}
if (line[0] == 'k' && line[1] == ':') {
if (currentSet == -1 || g_Key_Reply[currentSet].replyCount > 0) {
currentSet++;
}
strcpy(g_Key_Reply[currentSet].keywords[g_Key_Reply[currentSet].keywordCount], line + 2);
g_Key_Reply[currentSet].keywordCount++;
g_Key_ReplyCount = currentSet + 1;
} else if (line[0] == 'r' && line[1] == ':') {
strcpy(g_Key_Reply[currentSet].replies[g_Key_Reply[currentSet].replyCount], line + 2);
g_Key_Reply[currentSet].replyCount++;
}
}
fclose(file);
printf("number of keywords-replies pair groups %d\n", currentSet);
}
void loadSwapWords(const char* filename) {
FILE* file = fopen(filename, "r");
if (!file) {
printf("Error opening swap words file: %s\n", filename);
return;
}
char line[MAX_STRING_LENGTH];
while (fgets(line, sizeof(line), file) && wCnt < MAX_SWAP_WORDS) {
line[strcspn(line, "\n")] = 0; // Remove newline
if (line[0] == 's' && line[1] == ':') {
char* delimiter = strchr(line + 2, '>');
if (delimiter) {
*delimiter = '\0';
strcpy(wordIn[wCnt], line + 2);
strcpy(wordOut[wCnt], delimiter + 1);
wCnt++;
}
}
}
fclose(file);
}
char* swapWords(const char* input) {
if (!input) return NULL;
char* result = safe_strdup(input);
char* temp = malloc(strlen(input) * 2 + 1); // Allocate more space for worst-case scenario
if (!temp) {
free(result);
return NULL;
}
char* word = strtok(result, " ");
temp[0] = '\0';
while (word != NULL) {
bool swapped = false;
for (int i = 0; i < wCnt; i++) {
if (strcmp(word, wordIn[i]) == 0) {
strcat(temp, wordOut[i]);
strcat(temp, " ");
swapped = true;
break;
}
}
if (!swapped) {
strcat(temp, word);
strcat(temp, " ");
}
word = strtok(NULL, " ");
}
// Remove trailing space
int len = strlen(temp);
if (len > 0 && temp[len - 1] == ' ') {
temp[len - 1] = '\0';
}
free(result);
return temp;
}
char* processReply(const char* reply, const char* userInput) {
if (!reply || !userInput) return NULL;
char* processedReply = safe_strdup(reply);
int len = strlen(processedReply);
if (len > 0 && processedReply[len - 1] == '*') {
processedReply[len - 1] = '\0'; // Remove the asterisk
// Save the user's input to memory
if (memoryCount < MAX_MEMORY) {
strncpy(memory[memoryCount], userInput, MAX_STRING_LENGTH - 1);
memory[memoryCount][MAX_STRING_LENGTH - 1] = '\0';
memoryCount++;
}
// Find the keyword in the user's input
char* keyword = NULL;
for (int i = 0; i < g_Key_ReplyCount; i++) {
for (int j = 0; j < g_Key_Reply[i].keywordCount; j++) {
if (strstr(userInput, g_Key_Reply[i].keywords[j])) {
keyword = g_Key_Reply[i].keywords[j];
break;
}
}
if (keyword) break;
}
if (keyword) {
char* rest = strstr(userInput, keyword);
if (rest) {
rest += strlen(keyword);
char* swapped = swapWords(rest);
if (swapped) {
// Concatenate the swapped input to the reply
char* temp = malloc(strlen(processedReply) + strlen(swapped) + 2);
if (temp) {
sprintf(temp, "%s %s", processedReply, swapped);
free(processedReply);
processedReply = temp;
}
free(swapped);
}
}
}
}
return processedReply;
}
char* userQuestion(const char* txt) {
if (!txt) return NULL;
char* matchedReplies[MAX_MATCHES] = {NULL};
int matchCount = 0;
bool found = false;
char* combinedReply = NULL;
for (int i = 0; i < g_Key_ReplyCount && matchCount < MAX_MATCHES; i++) {
for (int j = 0; j < g_Key_Reply[i].keywordCount; j++) {
if (strstr(txt, g_Key_Reply[i].keywords[j])) {
int replyIndex = rand() % g_Key_Reply[i].replyCount;
matchedReplies[matchCount] = safe_strdup(g_Key_Reply[i].replies[replyIndex]);
matchCount++;
found = true;
break;
}
}
}
if (matchCount > 0) {
size_t totalLength = 1; // Start with 1 for the null terminator
for (int i = 0; i < matchCount; i++) {
char* processedReply = processReply(matchedReplies[i], txt);
if (processedReply) {
totalLength += strlen(processedReply) + 1; // +1 for newline
free(matchedReplies[i]);
matchedReplies[i] = processedReply;
}
}
combinedReply = malloc(totalLength);
if (combinedReply) {
combinedReply[0] = '\0';
for (int i = 0; i < matchCount; i++) {
if (matchedReplies[i]) {
strcat(combinedReply, matchedReplies[i]);
strcat(combinedReply, "\n");
free(matchedReplies[i]);
}
}
}
} else if (!found) {
if (default_reply_count > 0) {
int defaultIndex = rand() % default_reply_count;
combinedReply = safe_strdup(default_replies[defaultIndex]);
}
}
return combinedReply ? combinedReply : safe_strdup("I don't understand. Can you rephrase that?");
}
char* commands(char* txt) {
char* isolated = isolatePunctuation(txt);
for (int i = 0; isolated[i]; i++) {
isolated[i] = tolower(isolated[i]);
}
char* response = userQuestion(isolated);
free(isolated);
return response;
}
void speak(const char* text) {
char command[MAX_STRING_LENGTH * 2];
snprintf(command, sizeof(command), "voice -r -1 -n \"Microsoft David Desktop\" \"%s\"", text);
system(command);
}
int main() {
srand(time(NULL));
loadArrays("database.txt");
loadSwapWords("swapwords.txt");
printf("CHATBOT DANNY IN C PROGRAMMING LANGUAGE VERSION 1.1.6.5 (C) RON77\n");
char input[MAX_STRING_LENGTH];
char* response;
while (1) {
printf("> ");
if (fgets(input, sizeof(input), stdin) == NULL) {
break;
}
input[strcspn(input, "\n")] = 0; // Remove newline
if (strcmp(input, "quit") == 0) break;
response = commands(input);
if (response) {
// Split the response into separate lines and speak each one
char* line = strtok(response, "\n");
while (line != NULL) {
printf("%s\n", line);
speak(line);
line = strtok(NULL, "\n");
}
free(response);
} else {
printf("An error occurred while processing your input.\n");
}
}
return 0;
}
swapwords.txt
this chatbot used 'voice.exe' TTS cli engine wrapper on windows...
https://elifulkerson.com/projects/commandline-text-to-speech.php (https://elifulkerson.com/projects/commandline-text-to-speech.php)