Hi, ok, Iāll give you a little history to this. Iām using the spark as a sort of platform to learn C++ to have a real reason to do so while having a little fun along the way
I have been coding for years in C#, I did a degree in computer science in 2000, part of which was a C module which did include pointers which I understand. Having finished my course, I never used C again and used C# as it was much easier to achieve very quick results with, most of the lower stuff I didnāt have to deal with.
My mecca though has always been to learn C++ as I view this as the daddy of languages, able to get down low and dirty when needed and also able to opperate without frameworks, multi-platform and depending on level of experience, very efficient code is just keystrokes away ā¦
So, I also have an interest in the real world application of micro controllers, back along I bought some pics and tried to code onto them using mplab, way beyond me, machine code wo wo wo, um, no. So when Arduino came along I was in heaven, that led me to Spark and here we are.
I am now happily learning a great deal about electronics and C++. The only issue is that comming from a C# background, things in C++ are shal we say, more problematic.
The specific problem I have which relates to why I asked this question is this. I have a class I wrote whos job it is to load a list from a file. Initially I thought of doing this in a 2d char array. I donāt like using strings becuase in my Arduino days they were frowned upon as being inefficient and the library which just about supported them was buggy, so strings were a bit of a no no to me. So, the more complicated char array it is then. This brings me to functions. In C#, I could just return any old object from a function, not so it seems in C++. Well, I found out thatās not entirely true. In C# you can pass by ref like this
void function x(out int y)
or by value
int function x(int y)
This is how my brain works and so C++ is bending it with new concepts. In order to work with my desired char arrays, I have to be able to return a char array, I now realise I can do this as follows
void x(char y[])
being a this is the same as passing a pointer to the array which means the function will opperate on the contents of the memory pointed to by said pointer, thus changing the original array, no return value, ok.
The problem comes when we start throwing dereferencing (asterisk here) and address of & opperators around, I get really confused. Questions like, in a param list, does it tag on the end of the type like this char* y or does it go on the name like this
char (asterisk here)x,
do we even need it, is
char (asterisk here)x or char x the same as char x[], bloody astrisk, leave me alone!
Anyway, this is a long post and i havenāt even got to my specific problem yet. I have now encountered null terminated strings, O my goodsness, another fly in the ointment. So we have std srings, strings, character arrays, null terminated character arrays, c strings and goodness only knows what other types of strings, why on earth did someone go to all this effort to create multiple types whos only collective job in life is to hold an array of characters!
So, to my problem. Some code.
This method reads a file using the SD library. The data in said file is \n delimited, in rows of 8 string per camera preset names. So passing the camera number, ie 1, 2 3 etc, is supposed to read the first 8 lines if cam 1, lines 9-16 for cam 2 etc, which it does.
in data header I declare an array of strings thus
String camPresets[8];
int DataManager::load(int cam){
int index = 0;
currentCam = cam;
myFile = SD.open("test.txt");
if(!myFile)
return 2;
int line = 0;
int row = 0;
char buff[10];
std::fill_n(buff, 10, ' ');
while (myFile.available())
{
char c = myFile.read();
if(c == '\n')
{
if(line >= ((currentCam - 1) * 8) && line <= ((currentCam * 8) - 1))
{
camPresets[index] = buff;
index++;
}
if(line > ((currentCam * 8) - 1))
break;
line++;
row = 0;
}
else
{
buff[row] = c;
row++;
}
}
myFile.close();
return 0;
fail:
retrun 3;
}
The following method then prints the returned string to the screen. Except thereās a problem. The screen is in fact displaying an editable char array which the user, using a rotary encoder can traverse. So the display object has a global char array which it needs to display. Because of my lack of ability to pass char arrays around, I opted to use sting whenever I needed to return a, well, string from a function. So, the data gets read into a char array, converted to a string, then passed to the display, then converted back into a char array anf output to the screen and copied to the global char array using a for loop. This is great except not only do I see the string on the screen, I also see a buch of garbage on the end of the string.
String x = data.getPresetLabel(0); // gets a string from datas array camPresets[]
PrintTextEntryScreen(x); //call the display method.
void Display::PrintTextEntryScreen(String label)
{
digole.setPrintPos(0, 2, _TEXT_);
for(i=0; i < label.length(); i++)
{
userInput[i] = label.charAt(i);
digole.print(label.charAt(i));
}
}
for input string āStringOneā I get āStringOne pā on the screen.
Sorry this is such a long post and if you havnāt given up and gone home by this point then I applaud you.
Iām guessing there are two things going on here. 1. using my understanding of being able to pass by ref, I should do away with the strings and work only with char arrays and 2. my garbage on the end of my output, why is C++ doing this to me ?