I have a char array that i get from serial port (Arduino) . the data is separated by commas so its like this :
header:data
The chars array that holds this structure is pre defined like this : char content[50];
I am trying to write a function , that will get a parameter content
and return only the header
, and then another function to return only the data
. I know i have to start with this - but dont really know how to continue:
void getHeader( char* localString)
{
char delimiters[] = ":";
char *valPosition=NULL;
char newString=NULL ;
valPosition = strtok(localString, delimiters); //what is this doing ?
.... //whats now ?
//also how do you return the header to the argument
I have tried that according to an answer here ,but i get nothing to print:
char delimiters[] = ":";
char *valPosition=NULL;
char newString=NULL ;
char * header = NULL;
valPosition = strtok(content, delimiters);
malloc(strlen(valPosition) + 1);
strcpy(header, valPosition);
Serial.println(header);
Let's have a look at the man page for strtok()
. It says
char *strtok(char *str, const char *delim);
The
strtok()
function parses a string into a sequence of tokens..... Thedelim
argument specifies a set of bytes that delimit the tokens in the parsed string. ...... Each call tostrtok()
returns a pointer to a null-terminated string containing the next token.
That means, when you call
valPosition = strtok(localString, delimiters); /
strtok()
will search localString
for the delimiter specified in delimiters
and if it finds any, it will return the token as a null-terminated string.
Beware , strtok()
modify their first argument.
and
cannot be used on constant strings.
so, the localString
should be modifiable, ie, cannot be a string literal.
Next, as per your format, strtok()
will return the header
, without the :
.
so, you need to copy the returned string into another and return that. You can use dynamic memory allocation, as per following algorithm
char * header = NULL;
strtok()
, if not NULL, allocate memory to header
, like header = malloc(strlen(valPosition) + 1);
strcpy(header, valPosition);
header
from the function. I hope, you understand that you need to change the function prototype also return a pointer, like
char * getHeader( char* localString){....
Also, once you're done using the returned value, you need to free()
it.
If header:data
is the only use case you have you want to look for strchr()
.
Example:
#include <string.h> /* for strchr() and strlen() */
#include <errno.h> /* for EINVAL */
int get_header_and_data(const char * input, char ** pheader, char ** pdata)
{
int result = 0;
if (NULL == input
|| NULL == pheader || NULL == *pheader
|| NULL == pdata || NULL == *pdata
)
{
/* Trivial case of "no" input and/or missing references to store the result. */
errno = EINVAL;
result = -1;
}
else
{
char * pcolon = strchr(input, ':');
if (NULL == pcolon)
{
/* No delimiter found. */
errno = EINVAL;
result = -1;
}
else
{
/* Delimiter found. */
if (pcolon == input)
{
/* No header found. */
errno = EINVAL;
result = -1;
}
else
{
if (1 == strlen(pcolon))
{
/* No data found. */
errno = EINVAL;
result = -1;
}
else
{
/* Success. */
*pcolon = '\0';
++pcolon;
(*data) = pcolon;
(*pheader) = input;
}
}
}
}
return result;
}
and use it like this:
#include <stdio.h>
int get_header_and_data(const char *, char **, char **);
...
char content[50] = "";
/* Load content here. */
char * header = NULL;
char * data = NULL;
if (-1 == get_header_and_data(content, &header, &data)
{
perror("get_header_and_data() failed.");
abort(); /* Or what ever to handle the error. */
}
else
{
/* Dereference and/or use header and data here .*/
}
Please not that on success header
and data
(still) refer to the memory of content
, as well as that on success the latter is modifed.
Just for fun, the code above can be shrunk down to:
int get_header_and_data(const char * input, char ** pheader, char ** pdata)
{
int result = 0;
if (NULL == input
|| NULL == pheader || NULL == *pheader
|| NULL == pdata || NULL == *pdata
)
{
/* Trivial case of "no" input and/or missing references to store the result. */
errno = EINVAL;
result = -1;
}
else
{
char * pcolon = strchr(input, ':');
if (NULL == pcolon /* No delimiter found. */
|| pcolon == input /* No header found. */
|| 1 == strlen(pcolon) /* No data found. */
)
{
errno = EINVAL;
result = -1;
}
else
{
/* Success. */
*pcolon = '\0';
++pcolon;
(*data) = pcolon;
(*pheader) = input;
}
}
return result;
}
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.