我有一个来自串口(Arduino)的char数组。 数据用逗号分隔,如下所示:
header:data
保存此结构的chars数组预先定义如下:char content[50];
我正在尝试编写一个函数,它将获得一个参数content
并仅返回header
,然后返回另一个函数以仅返回data
。我知道我必须从这开始 - 但不知道如何继续:
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
我根据这里的答案尝试过,但我没有得到任何打印:
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);
答案 0 :(得分:3)
让我们看看strtok()
的{{3}}。它说
char *strtok(char *str, const char *delim);
strtok()
函数将字符串解析为一系列标记.....delim
参数指定一组字节,用于分隔已解析字符串中的标记。 ......每次调用strtok()
都会返回一个指向包含下一个标记的以空字符结尾的字符串的指针。
这意味着,当你打电话
valPosition = strtok(localString, delimiters); /
strtok()
会在localString
中搜索delimiters
中指定的分隔符
如果它找到任何,它将返回令牌作为以null结尾的字符串。
小心,strtok()
修改他们的第一个参数。
和
不能用于常量字符串。
所以,localString
应该是可修改的,即不能是字符串文字。
接下来,根据您的格式,strtok()
将返回header
,而不是:
。
所以,您需要将返回的字符串复制到另一个字符串并返回该字符串。您可以按照以下算法
使用动态内存分配char * header = NULL;
strtok()
的返回值,如果不是NULL,则将内存分配给header
,如header = malloc(strlen(valPosition) + 1);
strcpy(header, valPosition);
header
。我希望,你明白你需要更改函数原型也会返回一个指针,比如
char * getHeader( char* localString){....
此外,一旦您使用了返回的值,您需要free()
它。
答案 1 :(得分:1)
如果header:data
是唯一的用例,您可以查找strchr()
。
示例:
#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;
}
并像这样使用它:
#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 .*/
}
请注意,成功header
和data
(仍然)会引用content
的记忆,以及成功后记的内容。
为了好玩,上面的代码可以缩小为:
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;
}