Hello,
I'm trying to write a "chatbot" class which basically reads from a file to populate a hashmap which stores keywords and appropriate responses (this text adjusts based on 4 variables). I've been coding in java for a while and have already gotten an analogous version to work in that language, but I'm pretty new to C/C++ and especially new to Arduino code. \
The library tutorial suggests making a .h file and a .cpp file, but when I looked up a hashmap library, they combined all of that into the .h, so I tried doing that and have been getting an error I don't understand. When I separate it into the 2 files, I get other errors like the hashmap has no type. I'm including the code in 1 file, since I like that better as its more intuitive to me /similar to java.
This is an example of a library that uses the same HashMap I am using: GitHub - krohling/ArduinoPusherClient: An Arduino interface to Pusher (pusherapp.com)
The parts I'm uncertain about because I haven't yet been able to get the program to compile are: if I'm reading in the file correctly, or if I'm splitting the lines properly (found this code somewhere on the forum). I'm also wondering whether it's possible to set the capacity of the database hashmap to N initially, since the first line of the file will tell me how many keywords need to go into the hashmap.
/*
Note: file line can only have 15,000 chars ~ 100 responses per keyword
must have at least 2 responses
*/
#include <HashMap.h>
#include <QueueList.h>
#include <stdlib.h>
#include <SD.h>
#ifndef ChatBot_h
#define ChatBot_h
class ChatBot
{
public:
ChatBot(String brain, long duration, String defaultUser, String currentUser, String prevUser)
{
_brain = brain;
//resvSize = 4;
resv = HashMap<String, String, 4>();
setDuration(duration);
resv["defaultUser"] = defaultUser;
resv["currentUser"] = currentUser;
resv["prevUser"] = prevUser;
File file = SD.open(brain);
//read first line for N
char sizeBuff[10];
int idx = 0;
while(file.available())
{
char c = file.read();
if (c != '\n' && c != '\r')
{
sizeBuff[idx] = c;
idx++;
}
}
N = atoi(sizeBuff);
database = HashMap<String, QueueList<String>, 50>();
//read one line
char lineBuff[15000];
idx = 0;
while(file.available())
{
char c = file.read();
if (c != '\n' && c != "\r")
{
lineBuff[idx] = c;
idx++;
//begin parsing
char act[] = split(lineBuff, ":", 1);
char twts[] = split(lineBuff, ":", 2);
QueueList<String> resp;
int twtNo = 1; //number of tweets for this keyword
for (int i = 0; i < twts.strlen(); i++)
{
if (twts[i] == "/") twtNo++;
}
for (int i = 0; i < twtNo; i++)
{
char r[] = split(twts, "/", i);
resp.push(String(r));
}
database[String(act)] = resp;
}
idx = 0;
}
String getDuration()
{
return resv.valueAt("duration");
}
void setDuration(long d)
{
char buff[5];
String duration = "";
if (d < 1800000) duration = "not very long";
else if (d >= 1800000 && d < 2250000) duration = "30 mins";
else if (d >= 2250000 && d < 3150000) duration = "45 mins";
else if (d >= 3150000 && d < 3600000) duration = "1 hr";
else if (d >= 3600000 && d < 172800000) {
if ((d % 3600000) == 0) {
if (d == 3600000) duration = "1 hr";
else duration = d / 3600000 + " hrs";
}
else duration = dtostrf((float) d / 3600000,0,1,BUFFER) + "hrs";
} else if (d >= 172800000 && d < 604800000) duration = "days";
else if (d >= 604800000 && d < 907200000) duration = "1 wk";
else if (d >= 907200000 && d < 1512000000) duration = "2 wks";
else if (d >= 1512000000 && d < 2116800000) duration = "3 wks";
else if (d >= 2116800000 && d < 2721600000L) duration = "4 wks";
else duration = "a long time";
resv["duration"] = duration;
}
String getDefaultUser()
{
return resv.valueAt("defaultUser");
}
void setDefaultUser(String handle);
{
resv["defaultUser"] = handle;
}
String getCurrentUser()
{
return resv.valueAt("currentUser");
}
void setCurrentUser(String handle);
{
resv["currentUser"] = handle;
}
String getPrevUser()
{
return resv.valueAt("prevUser");
}
void setPrevUser(String handle);
{
resv["defaultUser"] = handle;
}
bool understands(String input);
{
return database.contains(input);
}
String respond(String input)
{
QueueList<String> q = database.valueAt(input);
String resp = q.pop();
q.push(resp);
for(int i = 0; i < resv.keys.size(); i++)
{
String s = resv.keys[i];
String regex = "_" + s;
resp.replace(regex, resv.valueAt(s));
}
return resp;
}
// Function to return a substring defined by a delimiter at an index
char* split (char* str, char *delim, int index)
{
char *act, *sub, *ptr;
static char copy[15000];
int i;
// Since strtok consumes the first arg, make a copy
strcpy(copy, str);
for (i = 1, act = copy; i <= index; i++, act = NULL)
{
sub = strtok_r(act, delim, &ptr);
if (sub == NULL) break;
}
return sub;
}
private:
//int N;
HashMap<String, QueueList<String>, 50> database; //can i use a variable capacity? used to be N
//int resvSize;
HashMap<String, String, 4> resv;
String _brain;
};
#endif
I'm actually calling it through another testing program which just serial outputs all the functions, but the errors I get are:
In file included from ChatBotTester.cpp:7:
ChatBot.h:15: error: expected `)' before 'brain'
ChatBotTester:61: error: expected `}' at end of input
ChatBotTester:61: error: expected unqualified-id at end of input
I''m sure there are other errors besides the ones initially picked up, so if you see any let me know! Thanks a lot!