error message while trying to write a class/library

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!

If you are using an arduino, doesn't matter what your error is, this will always give you a bad day.

static char copy[15000];

also

resv["defaultUser"]

if that is usable, what is really happening is, "defaultUser" is stored in sram then the pointer to it is used as a number to initialise resv, every time you edit your code, this could be referencing a completely different element.

Thanks for the quick reply! I was worried about the 15000 as well, though since I haven't been able to compile I haven't tested it. I basically want to "readLine()" keywords and their responses for example:

example:This is response 1/This is response 2/This is response3

which would be stored in a hashmap, which the keyword (example) as the key and a queue storing the responses as the value. The 15000 was just because I was hoping to have a lot of responses and I need a buffer large enough to handle long lines... they probably won't be quite that long, but right now each line is already 1000+ and I wanted to add more responses. Is there a number you suggest I should cap it at?

As for the resv["defaultUser"] part,
Here is a link to the example .pde that was with the HashMap library: http://wiring.uniandes.edu.co/source/trunk/wiring/firmware/libraries/HashMap/examples/HelloHashMap/HelloHashMap.pde?revision=1123&view=markup

In java when you try to insert a key that already exists in the hashmap it overwrites the previous value, so that's what I'm hoping to do... in the HelloHashMap example, they increment one of the values to change it, but I'm not storing ints, so I just wanted to replace the value string. Is there a way I could do that? Should I make a variable for the value and then point to that when I reset/I'm a little unsure how to do that (though I could mess around with it i I were able to get the program to run... still have compile time errors though)

Is there a number you suggest I should cap it at?

That depends on which Arduino you are using. A Mega has 8K of memory. The others have 2K. You won't get many 1K values in 2K of memory.

You need to start thinking in terms of what is realistic for the Arduino vs. what is possible for a PC.

Yeah, that's something I've been struggling with. I already have an Ethernet shield with an SD card slot, and am planning to buy external RAM which I read about at the bottom of another forum (Arduino Forum) and that looks like it goes on a Mega. Would this help or do you still think I'd run into major problems? It doesnt have to be 15000, but at the very least 2000 is needed.

That forum that I linked to talked about preprocessing data on a computer, but if at all possible I'd like for this to be a stand-alone thing.

Does anyone know what the

ChatBot.h:15: error: expected `)' before 'brain'

is? I'd love to start get all the syntax right so I can start ironing out the other bugs. Thanks!

Does anyone know what the ... is?

To decipher that error message, the key is the variable name. Look at how that variable is typed, and see if, given the set of include files used, the compiler should really be expected to know what that type is.

    ChatBot(String brain, long duration, String defaultUser, String currentUser, String prevUser)

What, exactly, is a String? Where is the type defined? Does the sketch tell the compiler that?

Answers:
String is an instance of a class.
The class is defined in WString.h.
No. You need to include WString.h in the header file or you need to include Arduino.h, which (eventually) includes WString.h.