Using a String uses a lot of program sketch space!

I have created a sketch that logs data points onto a Micro SD card. The sketch will count the number of files in the “LogFiles” folder, and then create another file that is that amount plus one.

I create the new file using the function below:

void createNewFile() {
  String FileName =  String("LogFiles/Log0") + fileCount + String(".csv");
  logFile = SD.open(FileName, FILE_WRITE);
}

The issues is that this function with strings uses an extra 1,792 bytes in my program! Is there a way to do what I want to do without using strings or lowering the program storage space?

Using "S"trings at all might be just the start of your troubles. You might use char instead, as is common practice.

char filename[] = "00000000.CSV";

and go on from there.

Nick_Pyner:
Using "S"trings at all might be just the start of your troubles. You might use char instead, as is common practice.

char filename[] = "00000000.CSV";

and go on from there.

That saves a lot of space using char! Thank you! But how would I implement the fileCount variable into the char? For example, I am currently doing this, but get the error: "initializer fails to determine size of 'FileName'"

char FileName[] = char("LogFiles/Log0") + fileCount;

I'm afraid what you are doing is meaningless, I just use the date as a filename and make new ones at midnight. So, at a guess it will be something like

sprintf(filename, "%04u.csv", fileCount);  //9999 files
fileCount++;

but I have no idea what makes the change, or why.

sprintf will pull in a lot of code also, so it's not really worth it, if you only use it in one place.

It easily can be done 'by hand'.

char fName[] = "LogFiles/Log00000.csv";
const byte lastDigit = sizeof(fName) - 6;

void nextFileName() {
  if (++fName[lastDigit] > '9') {
    fName[lastDigit] = 0;
    if (++fName[lastDigit - 1] > '9') {
      fName[lastDigit - 1] = 0;
      if (++fName[lastDigit - 2] > '9') {
        fName[lastDigit - 2] = 0;
        if (++fName[lastDigit - 3] > '9') {
          fName[lastDigit - 3] = 0;
        }
      }
    }
  }
}
void setup() {
  Serial.begin(250000);
  Serial.println(fName);
  nextFileName();
  Serial.println(fName);
}
void loop() {}
LogFiles/Log00000.csv
LogFiles/Log00001.csv

Whandall:
sprintf will pull in a lot of code also, so it's not really worth it, if you only use it in one place.

It easily can be done 'by hand'.

char fName[] = "LogFiles/Log00000.csv";

const byte lastDigit = sizeof(fName) - 6;

void nextFileName() {
  if (++fName[lastDigit] > '9') {
    fName[lastDigit] = 0;
    if (++fName[lastDigit - 1] > '9') {
      fName[lastDigit - 1] = 0;
      if (++fName[lastDigit - 2] > '9') {
        fName[lastDigit - 2] = 0;
        if (++fName[lastDigit - 3] > '9') {
          fName[lastDigit - 3] = 0;
        }
      }
    }
  }
}
void setup() {
  Serial.begin(250000);
  Serial.println(fName);
  nextFileName();
  Serial.println(fName);
}
void loop() {}





LogFiles/Log00000.csv
LogFiles/Log00001.csv

probably that should be (everywhere you overflow)fName[lastDigit] = '0'; // the char '0' not the null char

Absolutely :wink: the test was not deep enough.

char fName[] = "LogFiles/Log00000.csv";
const byte lastDigit = sizeof(fName) - 6;

void nextFileName() {
  if (++fName[lastDigit] > '9') {
    fName[lastDigit] = '0';
    if (++fName[lastDigit - 1] > '9') {
      fName[lastDigit - 1] = '0';
      if (++fName[lastDigit - 2] > '9') {
        fName[lastDigit - 2] = '0';
        if (++fName[lastDigit - 3] > '9') {
          fName[lastDigit - 3] = '0';
        }
      }
    }
  }
}
void setup() {
  Serial.begin(250000);
  Serial.println(fName);
  for (uint16_t i = 0; i < 3456; i++ ) {
    nextFileName();
  }
  Serial.println(fName);
}
void loop() {}
LogFiles/Log00000.csv
LogFiles/Log03456.csv

:slight_smile:

(I assume it's intended to not update the first 0 - ie max number is 9999)

I was inspired from the

char FileName[] = char("LogFiles/Log0") + fileCount;

which also has a leading zero and I reused the limit (which is really 10000 for the same format) from

sprintf(filename, "%04u.csv", fileCount);  //9999 files

I just made the 9999 up.

yeah, assumed so but weird decision from OP

  String FileName =  String("LogFiles/Log0") + fileCount + String(".csv");