Issues with creating a library

I have a problem writing a library. I'd like to create one that usues the GetCSV.Value(pass variables here) and GetCSV.Count(pass variables here) functions and returns the data.

My sorry excuse for code is below.

// --------------------------------------------------------------------
// The intent of the libray is:
// String value = GetCSV.Value(String data, char separator, int index);
// int count = GetCSV.Count(String data, char separator);
// --------------------------------------------------------------------

// ----------------------------------------------------------------
//The GetCSV.h file

#ifndef GetCSV_h
#define GetCSV_h
#include "Arduino.h"

class GetCSV{
  public:
    String Value(String data, char separator, int index);
    int Count(String data, char separator);
};

#endif
// End of GetCSV.h ------------------------------------------------


// ----------------------------------------------------------------
// The GetCSV.cpp file

String GetCSV::Value(String data, char separator, int index) {
// Do stuff here and return a String value
}

int GetCSV::Count(String data, char separator) {
// Do stuff here and return an integer value
}
// End of GetCSV.cpp -----------------------------------------------

// ----------------------------------------------------------------
// The Arduino Code

#include "GetCSV.h"

String x = "c,d,e,f";
void setup() {
  String z = GetCSV.Value(x, ',' 0);
  int y = GetCSV.Count(x, ',');
  }

void loop() {}

But when I try to compile it, the IDE throws an error telling me "expected primary-expression before '.' token"

I'm likey missing something really stupid here. But there's little info out there regarding a class that uses a period and a name. If anyone can help here I would be forever grateful.

You need to create an instance of a class before you can use it

So how do I go about doing that with the code I wrote? I'd to learn more on how this is done but like I mentioned, there's little info out there regarding a class that uses a period and a name.

Either way I thank you for your kind reply.

there's little info out there

Idk about that

When I use Serial.print() I don't define an instance of Serial. Yet I can still call the underlying functions after the period. This is the question that's been giving me grief.

I could create a class that can be defined as an instance in the program but I would like the user (me) to use the name GetCSV without having it declared in the program. That's where the info gets harder to find online.

I hope that all made sense.

P.S. Have patience with me. I'm a 65 year old retired industrial electrian that loves spending time playing with microprocessors and trying to learn more.

Add #include "GetCSV.h" to the top of GetCSV.cpp so the compiler knows what you are talking about when you start defining member functions.

Change your class name to _GetCSV and add this line to the end of GetCSV.h:
extern _GetCSV GetCSV;

Then add this line to the end of GetCSV.cpp to define the global instance:
_GetCSV GetCSV;

The reason you can use Serial is because it's an already instantiated/declared HardwareSerial class. The instantiation/declaration happens in the core source files. You can do something similar in your library if you want.

I made the changes that johnwasser suggested but I'm still not getting it.

Here is the code I have at this point that is unfortunately still not compiling. I'm sure the issue will be self apparent to most. Just not myself.

GetCSV_Test.h

#include "GetCSV.h"

String x = "c,d,e,f";

void setup() {
  Serial.begin(115200);
  String z = GetCSV.Value(x, ',' 0);
  Serial.println(z);
  int y = GetCSV.Count(x, ',');
  Serial.println(y);
}

void loop() {}

GetCSV.h

#ifndef GetCSV_h
#define GetCSV_h
#include "Arduino.h"

class _GetCSV {
  public:
    String Value(String data, char separator, int index);
    int Count(String data, char separator);    
};
extern _GetCSV GetCSV;
#endif

And GetCSV.cpp

#include "GetCSV.h"

//==================================================
//                  GetCSV.h
//          Routine used to parse CSV
//==================================================

_GetCSV::_GetCSV {}

// -------------------------------------------------
// Returns the CSV value at a given position index
// Returns NULL if no value is found
// -------------------------------------------------

_GetCSV::Value(String data, char separator, int index) {
    int found = 0;
    int strIndex[] = {0, -1};
    int maxIndex = data.length()-1;
    for(int i=0; i<=maxIndex && found<=index; i++){
      if(data.charAt(i)==separator || i==maxIndex){
        found++;
        strIndex[0] = strIndex[1]+1;
        strIndex[1] = (i == maxIndex) ? i+1 : i;
      }
    }  
    return found>index ? data.substring(strIndex[0], strIndex[1]) : "NULL";
  }
  
// -------------------------------------------------
// Returns the number of objects in the CSV string
// -------------------------------------------------

_GetCSV::Count(String data, char separator) {
    int csvLength;
    int thelength = data.length() - 1;
    if(data.charAt(thelength) == separator) csvLength = 0; else csvLength = 1;
    for(int i=0; i<=thelength; i++) {
      if(data.charAt(i) == separator) {
          csvLength++;
      }      
    }
    return csvLength;
  }
}
_GetCSV GetCSV;

Thanks for the help so far. It's appreciated.

I fixed the issues such that it compiles. I left notes in the comments as to what needed to be changed:

.ino

#include "GetCSV.h"

String x = "c,d,e,f";

void setup() {
  Serial.begin(115200);
  String z = GetCSV.Value(x, ',', 0); // add missing comma
  Serial.println(z);
  int y = GetCSV.Count(x, ',');
  Serial.println(y);
}

void loop() {}

.h

#ifndef GetCSV_h
#define GetCSV_h
#include "Arduino.h"

class _GetCSV {
  public:
    String Value(String data, char separator, int index);
    int Count(String data, char separator);    
};
extern _GetCSV GetCSV;
#endif

.cpp

#include "GetCSV.h"

//==================================================
//                  GetCSV.h
//          Routine used to parse CSV
//==================================================

// _GetCSV::_GetCSV {} // Remove this

// -------------------------------------------------
// Returns the CSV value at a given position index
// Returns NULL if no value is found
// -------------------------------------------------

String _GetCSV::Value(String data, char separator, int index) { // Add return type
    int found = 0;
    int strIndex[] = {0, -1};
    int maxIndex = data.length()-1;
    for(int i=0; i<=maxIndex && found<=index; i++){
      if(data.charAt(i)==separator || i==maxIndex){
        found++;
        strIndex[0] = strIndex[1]+1;
        strIndex[1] = (i == maxIndex) ? i+1 : i;
      }
    }  
    return found>index ? data.substring(strIndex[0], strIndex[1]) : "NULL";
  }
  
// -------------------------------------------------
// Returns the number of objects in the CSV string
// -------------------------------------------------

int _GetCSV::Count(String data, char separator) { // Add return type
    int csvLength;
    int thelength = data.length() - 1;
    if(data.charAt(thelength) == separator) csvLength = 0; else csvLength = 1;
    for(int i=0; i<=thelength; i++) {
      if(data.charAt(i) == separator) {
          csvLength++;
      }      
    }
    return csvLength;
  }
// } // Remove this
_GetCSV GetCSV;
1 Like

First off, let me thank you for your kind help. :+1:

All the documentation I could find did not cover using a library to return a value. Only to pass a value or values to the function to perform a task in of itself. It should have dawned on me that I needed to treat this as I would have using a function and assign a return type to it. :person_facepalming:

And this exercise has helped me to better understand the concepts of classes and instances of a class.

Thank you all for your help and understanding. I really do appreciate it.

Retired Dave

1 Like

Just one more quick question if I may.

If I remove "extern _GetCSV GetCSV;" from the .h file and "_GetCSV GetCSV;" from the .cpp file I would then need to create an instance of the class to use it? Sounds right to me anyway.

Thanks.

EDIT: I just tried it and found I needed to create the instance in the ino file to use it.
Question answered and marked as solved.

Sorry Power_Broker for the quick self answer to my question regarding removing the instance. I noticed you agreed just after my edit and before your post was deleted and I apprieciate the reply. Thanks so much for the help.

1 Like

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.