如何将字符串标记保存到char变量?

时间:2011-09-05 12:25:54

标签: c char arduino strtok

我有一个使用udp发送的字符串。现在我想读取字符串,将其标记化并将其保存到char数组中。只保存每个单词的第一个字母。所以我只需要从element01到element05获得5个e。我在Arduino工作,我知道一些c#但没有c或c ++。

//p_params->packetBuffer contains the following string:
//element01#element02#element03#element04#element05

void packtStriper( receivedPacket * p_params )
{
  char delims[] = "#";
  char *result = NULL;
  int i = 0;

  //Tokenize string - 'split' it on hash mark
  result = strtok( p_params->packetBuffer, delims );

  //Iterate through the tokens and save them to my list
  while( result != NULL )
  {
    p_params->listData[i] = *result;
    i++;

    result = strtok( NULL, delims );
  }

  //Display the data just received
  for(int j =0; j<i; j++)
  {
    Serial.print( "Data " );
    Serial.print( j );
    Serial.print( ": " );

    Serial.println( p_params->listData[j] );
  } 
}

typedef struct receivedPacket
{
  char            * REQType;
  char            * confName;
  unsigned  int   confData[64];
  char            listData[10];
  char            packetBuffer[UDP_BUFFER_SIZE];
  int             packetSize;
  int             inProduction;

}receivedPacket;

由于以下代码打印了完整的元素名称,我认为我只能使用结果。但这也会返回错误。

char str[] = "element01#element02#element03#element04#element05";
char delims[] = "#";
char *result = NULL;
result = strtok( str, delims );
while( result != NULL ) {
    printf( "result is \"%s\"\n", result );
    result = strtok( NULL, delims );
}

2 个答案:

答案 0 :(得分:3)

以下一行:

p_params->listData[i] = *result

获取result的第一个字符,并将其复制到i的{​​{1}}个字符。因此,只复制每个令牌的第一个字符。你期望得到那些令牌,作为element01element02element03element04element05的一个序列,还是作为一个字符串数组?

请记住,在C和C ++中,chars数组只包含一个字符串,只需放入。要保存多个字符串,您需要一个字符数组数组或一些分隔符(这是您已经开始的地方......)。

修改

如果您想获得一个字符串数组,可以使用以下内容:将p_params->listData声明为

listData

这意味着char* listData[10]; 现在最多可以容纳10个字符串。然后,不要将listData分配给*result,而是使用以下内容:

listData[i]

将创建字符串的副本,并将其存储在下一个条目中。

注意:

  1. 如果要显示字符串,则必须再次循环,然后逐个打印。你不能只打印它们的整个阵列。
  2. p_params->listData[i] = strdup(result); 为您分配内存。完成后,您必须strdup这些字符串。
  3. 您的代码使用了魔术数字,这很糟糕。我假设这只是为了让你更容易阅读;)
  4. 如果您获得的元素超过10个,则会出现缓冲区溢出,因为free()最多只能容纳10个字符串。您应该至少确保listData左右i不超过9。

答案 1 :(得分:2)

result是指向字符的指针(可以是字符数组中的元素),而*result是指向的字符。这一行

p_params->listData[i] = *result;

将字符放入p_params->listData[i]

在C中,字符串由char类型的数组表示,并且通常以null结尾(即值0)。听起来你需要一个字符串数组,你可以创建一个二维数组。例如:

// 5 strings each with 9 characters and a null terminator
char ArrayOfStrings[5][10];

然后,您可以使用strcpy()strncpy()函数将一个标记复制到每个字符串中。我建议使用strncpy()来保证安全(所以你不要复制比空格更多的字符),并手动将每个字符串的最后一个元素设置为null。