I saw some code that had this neat function, and I'm wondering if it is possible and/or if it would benefit me here in this example. Would it make my code smaller/neater to somehow use the strcpy() function here. I'm not sure what I need to eliminate though. Currently, I loop thru the string characters and copy them 1 by 1. (around line 12 in this sample)
void next3Files() { //opens the next file on the SD card
for (int a = 0; a < 3; a++) { //loop thru 3 files
File entry = dir.openNextFile();
if (! entry) { //there isn't a next file
entry.close(); //close the entry
dir.rewindDirectory(); //rewind
entry = dir.openNextFile(); //get the first file
}
entryName = entry.name();
entry.close();
int len = strlen(entryName); //how long is the name?
memset(names[a], 0, sizeof(names[a])); //delete the previous value. Is this necessary?
for (int i = 0; i < len; i++) {
names[a][i] = entryName[i];
}
}
}
Then, when I print the 3 names to the LCD display I use this code. Is there a way to just print the name, without having to loop thru each character, or is what I'm doing the best way? (About line 12 and 13)
void Select_Part() {
do { //keep looping through names until they select one
next3Files(); //get the next 3 file names
disp.lcd_cls(); //clear display
for (int a = 0; a < 3; a++) { //loop thru 3 names
int len = strlen(names[a]); //how long is the name?
disp.lcd_rowcol(a, 0); //row, col
disp.lcd_print(a + 1); //the selection number
disp.lcd_print(F(": ")); //the selection number suffix
DEBUG_PRINT(a + 1); //the selection number
DEBUG_PRINT(": "); //the selection number suffix
for (int i = 0; i < len - 4; i++) {
disp.lcd_print(names[a][i]); //the filename
DEBUG_PRINT(names[a][i]); //the filename
}
DEBUG_PRINTLN();
}
disp.lcd_print("4. MORE 5. CANCEL"); //4 OR 5 TO SEE MORE FILE NAMES OF CANCEL
DEBUG_PRINTLN("4. MORE 5. CANCEL"); //4 OR 5 TO SEE MORE FILE NAMES OF CANCEL
DEBUG_PRINTLN();
while (1) { //wait for key input
byte k = checkKeyBuffer(); //get a keypress from the user
switch (k) {
case 1:
drillHole(names[0], 1); //drill selection 1
return; //after drilling the part, we'll return to main menu
case 2:
drillHole(names[1], 1); //drill selection 2
return; //after drilling the part, we'll return to main menu
case 3:
drillHole(names[2], 1); //drill selection 3
return; //after drilling the part, we'll return to main menu
case 4:
//show the next 3 files
break; //exit the key input loop to show the next 3 entries
case 5: //cancel
return;
case keyTimeout: //user input timed out
return;
}
}
}
while (1); //until break
}
Without knowing what 'disp' exactly is, it's difficult to answer your second question. With the 'normal' LCD, you can simply print the string
// print name on lcd
lcd.print(names[a]);
// go to next line on lcd
lcd.setCursor(n,0);
For the first question, you're not copying the terminating nul character. So the answer to your comment 'is this necessary' is yes. If you use strcpy(), you don't need the strlen(), memset() and don't need the loop.
Get used to using the length-limited versions of those functions. strncpy() should always be your default and only use strcpy() in an emergency.
Lazily using strcpy() has cost the computer industry billions with viruses taking advantage of the possibilities of overflow. Your Arduino can't catch a virus but it will save you lots of hours debugging a seemingly-random fault because one function wrote past the end of its assigned buffer.
MorganS:
Get used to using the length-limited versions of those functions. strncpy() should always be your default and only use strcpy() in an emergency.
Lazily using strcpy() has cost the computer industry billions with viruses taking advantage of the possibilities of overflow. Your Arduino can't catch a virus but it will save you lots of hours debugging a seemingly-random fault because one function wrote past the end of its assigned buffer.
I disagree although all points of view are OK. I would say don't use strncpy() by default, it will get you in trouble or adds un-necessary bound checks if you know what you are doing or if you don't it will sometimes leave you with a string that is not properly terminated by a '\0'
You need to use strncpy only when it is useful, not as a replacement for not overflowing your char array.
There are strlcpy() and strlcat() functions to copy and concatenate strings respectively that are designed to be safer, more consistent, and less error prone replacements for strncpy() and strncat(). They add a bit of error checking cost all the time that is safe but unecessary if you know want you do...
In my application, the string I'm copying, a filename from an SD card, will always be a maximum of 8 characters plus the extension, so 12 characters. And the names[a] variable is defined as 13 characters, so I won't have to worry about the string being too big. I do have a tight budget on sketch size, so is the best and most memory saving way for me to use this one?
strcpy(names[a], entryName);