Replacing String with char array[x]

Hi All,

Still continuing my battle and trying to remove all Strings from my app.

App Desired Behaviour:

  1. System boot
  2. Init structure:
typedef struct {
  uint32_t magic;
  char email[40];
} eepromConfig
  1. System checks eeprom for magic bytes. If magic bytes are different then set structure values to default values. Essentially I want to set email to empty by default.
char init_email[40] = "";
config_data.magic = DATA_MAGIC;
strcpy (config_data.email, init_email);
  1. Email remains an empty string until it is set via a particle function.
int setEmail(String command) {
  strcpy (config_data.email, command);
  storeConfigVariables(); // This just writes the struct to eeprom
	return 1;   
}
  1. Email is included as a variable in publish statements even when empty.

Just want to sanity check that my approach above is reasonable.

1 Like

@StngBo, for the initialization, you can let the compiler do the work:

// Create a struct typedef named eepromConfig with the defined member variables
typedef struct eepromConfig {
  uint32_t magic;
  char email[40];
};

// Create a global structure variable of the type previously defined and assign values to each member
eepromConfig config_data = { DATA_MAGIC, "" };

However, for the Particle.function(), command is an Arduino String while config is a c-string. As such, you need to use the c_str() function of the String class to convert it to a c-string:

int setEmail(String command) {
  strcpy (config_data.email, command.c_str());
  storeConfigVariables(); // This just writes the struct to eeprom
  return 1;   
}

:smiley:

5 Likes

An alternative to Paul’s suggestions (with the benefit to not overshoot the array boundaries :wink: )

int setEmail(const char* command) {
  int retVal = strncpy(config_data.email, command, sizeof(config_data.email)-1);
  ...
  return retVal; // use the return value to communicate something at least 
                 // somewhat useful like the length of the actually copied string
                 // or the result of the storeConfigVariables() call 
}

works just as well.

Additionally, if you ever want to wipe the content of the array entirely you can use

  memset(config_data.email, 0, sizeof(config_data.email));

consequently I’d add this to storeConfigVariables()

bool storeConfigVariables(const char* email = NULL, bool cleanSlate = false) {
  bool retVal = false;

  if (cleanSlate) {
    memset(config_data, 0, sizeof(config_data));
    config_data.magic = DATA_MAGIC;
  }
  if (email) {
    strncpy(config_data.email, email, sizeof(config_data.email)-1);
  }

  ...

  return retVal;
}
7 Likes

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