function splitter
is designed to get a string of parameters and create a an array of parameters. If only part of parameters were given, the rest of them will get default values.
for example : input string 1,2,3,4
would fill parameters
array with values {"1","2","3","4"}
, but if input string is 1,2
, parameters={"1","2","20","0"}
while parameters[3]
and parameters[2]
were given its default values.
BUT
when assigning default values, inside splitter
the correct values are stored in parameters
but when using print_output
function to show parameters
values - different values are shown.
in output supplied, when input is 1,2
, default values should be pasted, to parameters[2]
, and parameters[3]
, while input is 1,2,3,4
no need to use defaults.
OUTPUT:
Running string 1,2
param_2 was set to default value:20
param_3 was set to default value:0
output:
1
2
0
0
Running string 1,2,3,4
output:
1
2
3
4
CODE:
#define PARAM_AMOUNT 4
#define COLOR 1
#define LED_DELAY 20
#define BRIGHTNESS 50
#define LED_DIRECTION 0
char *parameters[PARAM_AMOUNT] = {"0", "0", "0", "0"};
int param_def[] = {COLOR, BRIGHTNESS, LED_DELAY, LED_DIRECTION};
void setup() {
Serial.begin(9600);
Serial.println("Running string 1,2");
splitter("1,2");
print_output();
Serial.println("Running string 1,2,3,4");
splitter("1,2,3,4");
print_output();
}
void splitter(char *inputstr) {
char * pch;
int i = 0;
pch = strtok (inputstr, " ,.-");
while (pch != NULL)
{
parameters[i] = pch;
pch = strtok (NULL, " ,.-");
i++;
}
// update default values
for (int n = i ; n <= PARAM_AMOUNT - 1; n++) {
sprintf(parameters[n], "%d", param_def[n]);
Serial.print("param_");
Serial.print(n);
Serial.print(" was set to default value:");
Serial.println(parameters[n]);
delay(50);
}
}
void print_output() {
Serial.println("output:");
for (int n = 0 ; n <= PARAM_AMOUNT - 1; n++) {
Serial.println(parameters[n]);
}
}
void loop() {
// put your main code here, to run repeatedly:
}
1 Answer 1
It is not a good practice to reserve memory for a string with a constant string. Allocate an array of char arrays with:
char parameters[PARAM_AMOUNT][PARAM_LEN];
Now with "0" you allocate 2 bytes for each string. The '0' and a terminating 0.
Then in splitter
function you write 3 bytes into one of the parameters with value "20". This writes outside of the 2 bytes of memory reserved for the string.
strcpy(parameters[i], pch);
will copy the token returned by strtok
into your array. pch
points into inputstr
and the delimiters in inputstr
are replaced by 'strtok' with zeros
-
Thank you. But but when
parameters
is not a pointer array, it can't getpch
value... ( I guess I'm still newbie here :( )guyd– guyd2019年03月01日 19:05:40 +00:00Commented Mar 1, 2019 at 19:05 -
paramaters[i]=pch;
was changed tosprintf(parameters[i],"%s",pch);
now all is OKguyd– guyd2019年03月01日 19:12:30 +00:00Commented Mar 1, 2019 at 19:12
n <= PARAM_AMOUNT - 1
. writen < PARAM_AMOUNT