将拆分后的字符串存储在数组中
Store splitted string in array
我使用 strtok() 拆分字符串并存储在数组中,如下所示
char *table[5];
char buffer[50] = {"1-Study"}; // The value is example, get new value by user
char *number;
char *name;
uint8_t tableNumber;
number = strtok(buffer, "-"); //equals "1"
name = strtok(NULL, "-"); //equals "Study"
tableNumber = atoi(number); //convert char to int
table[tableNumber] = name;
for (c = 0; c < 5; c++)
{
printf("table %d = %s\n", c, table[c]);
}
输入 5 次后结果应为:
table 0 = Study
table 1 = Sleep
table 2 = Party
table 3 = Hello
table 4 = Exit
但结果是:
table 0 = Exit
table 1 = Exit
table 2 = Exit
table 3 = Exit
table 4 = Exit
有什么问题?
请帮帮我?
谢谢
完整代码:
char gMessageBuffer[40];
char *gSceneTable[13];
boolean emberAfPreMessageReceivedCallback(EmberAfIncomingMessage* incomingMessage)
{
if (incomingMessage->apsFrame->profileId == HA_PROFILE_ID)
{
if (incomingMessage->apsFrame->clusterId == ZCL_SCENES_CLUSTER_ID)
{
MEMCOPY(gMessageBuffer, incomingMessage->message, incomingMessage->msgLen); // Get incoming message
gMessageBuffer[incomingMessage->msgLen] = '[=13=]';
emberEventControlSetDelayMS(getScenePayloadEventControl, SCENE_ACTION_TRESH);
return true;
}
}
return false;
}
void getScenePayloadEventFunction(void)
{
char *sceneNumber;
char *sceneName;
char *sceneID;
char *sceneAction;
uint8_t sceneTableNumber;
emberAfCorePrintln("///Incoming Message: %s///", gMessageBuffer);
sceneNumber = strtok(gMessageBuffer, ".");
sceneName = strtok(NULL, ".");
sceneID = strtok(NULL, ".");
sceneAction = strtok(NULL, ".");
emberAfCorePrintln("///SCENE NUMBER: %s///", sceneNumber);
emberAfCorePrintln("///SCENE NAME: %s///", sceneName);
emberAfCorePrintln("///SCENE ID: %s///", sceneID);
emberAfCorePrintln("///SCENE ACTION: %s///", sceneAction);
if (strcmp(sceneAction, "Update") == 0)
{
sceneTableNumber = atoi(sceneNumber);
gSceneTable[sceneTableNumber] = strdup(sceneName);
}
emberEventControlSetInactive(getScenePayloadEventControl);
}
这是用于 simplicity studio 中的微控制器 IDE。
我在 emberAfPreMessageReceivedCallback 中正确获取了负载
我把它分成 4 个部分并正确打印。
但是在将 sceneName 复制到 gSceneTable 数组后,我看到 gSceneTable 的所有元素中的最后一个 sceneName 为 gSceneTable[sceneTableNumber] = sceneName 并且我看到 "p]" 为 gSceneTable[sceneTableNumber] = strdup(sceneName);
示例代码:
输入类似 "sceneNumber.sceneName.sceneID.Update"
的消息
例如:1.Study.12345.Update
#include <stdio.h>
#include <string.h>
#include <conio.h>
char *gSceneTable[13];
char gMessageBuffer[50];
int main()
{
char *sceneNumber;
char *sceneName;
char *sceneID;
char *sceneAction;
int sceneTableNumber;
int check;
int c;
printf("Enter payload for 3 Times\r\n");
while(check != 3)
{
scanf("%s", &gMessageBuffer);
printf("Message is: %s\r\n",gMessageBuffer);
sceneNumber = strtok(gMessageBuffer, ".");
sceneName = strtok(NULL, ".");
sceneID = strtok(NULL, ".");
sceneAction = strtok(NULL, ".");
printf("%s\r\n", sceneNumber);
printf("%s\r\n", sceneName);
printf("%s\r\n", sceneID);
printf("%s\r\n", sceneAction);
if (strcmp(sceneAction, "Update") == 0)
{
sceneTableNumber = atoi(sceneNumber);
gSceneTable[sceneTableNumber] = sceneName;
}
check++;
}
for (c = 0; c < 4; c++)
{
printf("Scene Table: %d ----- %s \r\n", c, gSceneTable[c]);
}
return 0;
}
您的程序极不可能产生发布的输出。代码片段仅处理单个字符串并且 char *table[5];
未初始化,因此打印 table[0]
、table[2]
、table[3]
和 table[4]
中的字符串具有未定义的行为。您指定从文件中读取字符串,需要发布完整的程序才能进行精确和正确的分析。如果文件没有涵盖所有条目,则不初始化数组是一个问题,将无法判断哪些已设置,哪些未设置。
假设您的程序从文件或标准输入中读取字符串,使用 strtok
returns 指向源字符串的指针解析它们,这是您从文件中读取行的数组.因此,table[]
数组中的所有条目都指向该数组中的相同字节,这解释了您获得的输出:最后一行内容的 5 倍。
您应该复制存储在 table 中的字符串:
table[tableNumber] = strdup(name);
这是一个完整的修改后的程序:
#include <stdio.h>
#include <string.h>
int main() {
char *table[5] = { NULL, NULL, NULL, NULL, NULL };
char buffer[50];
char *number;
char *name;
int tableNumber;
for (int i = 0; i < 5; i++) {
if (!fgets(buffer, sizeof buffer, stdin))
break;
number = strtok(buffer, "-");
if (number == NULL) {
printf("empty line\n");
continue;
}
name = strtok(NULL, "-\n");
if (name == NULL) {
printf("no name after -\n");
continue;
}
tableNumber = atoi(number);
if (tableNumber < 0 || tableNumber >= 5) {
printf("invalid number: %d\n", tableNumber);
continue;
}
table[tableNumber] = strdup(name);
}
for (int i = 0; i < 5; i++) {
if (table[i])
printf("table %d = %s\n", i, table[i]);
}
for (int i = 0; i < 5; i++) {
free(table[i]);
}
return 0;
}
如果你的目标系统不支持strdup()
,使用这个:
#include <stdlib.h>
#include <string.h>
char *mystrdup(const char *s) {
size_t size = strlen(s) + 1;
char *p = malloc(size);
return (p != NULL) ? memcpy(p, s, size) : NULL;
}
我使用 strtok() 拆分字符串并存储在数组中,如下所示
char *table[5];
char buffer[50] = {"1-Study"}; // The value is example, get new value by user
char *number;
char *name;
uint8_t tableNumber;
number = strtok(buffer, "-"); //equals "1"
name = strtok(NULL, "-"); //equals "Study"
tableNumber = atoi(number); //convert char to int
table[tableNumber] = name;
for (c = 0; c < 5; c++)
{
printf("table %d = %s\n", c, table[c]);
}
输入 5 次后结果应为:
table 0 = Study
table 1 = Sleep
table 2 = Party
table 3 = Hello
table 4 = Exit
但结果是:
table 0 = Exit
table 1 = Exit
table 2 = Exit
table 3 = Exit
table 4 = Exit
有什么问题?
请帮帮我?
谢谢
完整代码:
char gMessageBuffer[40];
char *gSceneTable[13];
boolean emberAfPreMessageReceivedCallback(EmberAfIncomingMessage* incomingMessage)
{
if (incomingMessage->apsFrame->profileId == HA_PROFILE_ID)
{
if (incomingMessage->apsFrame->clusterId == ZCL_SCENES_CLUSTER_ID)
{
MEMCOPY(gMessageBuffer, incomingMessage->message, incomingMessage->msgLen); // Get incoming message
gMessageBuffer[incomingMessage->msgLen] = '[=13=]';
emberEventControlSetDelayMS(getScenePayloadEventControl, SCENE_ACTION_TRESH);
return true;
}
}
return false;
}
void getScenePayloadEventFunction(void)
{
char *sceneNumber;
char *sceneName;
char *sceneID;
char *sceneAction;
uint8_t sceneTableNumber;
emberAfCorePrintln("///Incoming Message: %s///", gMessageBuffer);
sceneNumber = strtok(gMessageBuffer, ".");
sceneName = strtok(NULL, ".");
sceneID = strtok(NULL, ".");
sceneAction = strtok(NULL, ".");
emberAfCorePrintln("///SCENE NUMBER: %s///", sceneNumber);
emberAfCorePrintln("///SCENE NAME: %s///", sceneName);
emberAfCorePrintln("///SCENE ID: %s///", sceneID);
emberAfCorePrintln("///SCENE ACTION: %s///", sceneAction);
if (strcmp(sceneAction, "Update") == 0)
{
sceneTableNumber = atoi(sceneNumber);
gSceneTable[sceneTableNumber] = strdup(sceneName);
}
emberEventControlSetInactive(getScenePayloadEventControl);
}
这是用于 simplicity studio 中的微控制器 IDE。
我在 emberAfPreMessageReceivedCallback 中正确获取了负载 我把它分成 4 个部分并正确打印。
但是在将 sceneName 复制到 gSceneTable 数组后,我看到 gSceneTable 的所有元素中的最后一个 sceneName 为 gSceneTable[sceneTableNumber] = sceneName 并且我看到 "p]" 为 gSceneTable[sceneTableNumber] = strdup(sceneName);
示例代码:
输入类似 "sceneNumber.sceneName.sceneID.Update"
的消息例如:1.Study.12345.Update
#include <stdio.h>
#include <string.h>
#include <conio.h>
char *gSceneTable[13];
char gMessageBuffer[50];
int main()
{
char *sceneNumber;
char *sceneName;
char *sceneID;
char *sceneAction;
int sceneTableNumber;
int check;
int c;
printf("Enter payload for 3 Times\r\n");
while(check != 3)
{
scanf("%s", &gMessageBuffer);
printf("Message is: %s\r\n",gMessageBuffer);
sceneNumber = strtok(gMessageBuffer, ".");
sceneName = strtok(NULL, ".");
sceneID = strtok(NULL, ".");
sceneAction = strtok(NULL, ".");
printf("%s\r\n", sceneNumber);
printf("%s\r\n", sceneName);
printf("%s\r\n", sceneID);
printf("%s\r\n", sceneAction);
if (strcmp(sceneAction, "Update") == 0)
{
sceneTableNumber = atoi(sceneNumber);
gSceneTable[sceneTableNumber] = sceneName;
}
check++;
}
for (c = 0; c < 4; c++)
{
printf("Scene Table: %d ----- %s \r\n", c, gSceneTable[c]);
}
return 0;
}
您的程序极不可能产生发布的输出。代码片段仅处理单个字符串并且 char *table[5];
未初始化,因此打印 table[0]
、table[2]
、table[3]
和 table[4]
中的字符串具有未定义的行为。您指定从文件中读取字符串,需要发布完整的程序才能进行精确和正确的分析。如果文件没有涵盖所有条目,则不初始化数组是一个问题,将无法判断哪些已设置,哪些未设置。
假设您的程序从文件或标准输入中读取字符串,使用 strtok
returns 指向源字符串的指针解析它们,这是您从文件中读取行的数组.因此,table[]
数组中的所有条目都指向该数组中的相同字节,这解释了您获得的输出:最后一行内容的 5 倍。
您应该复制存储在 table 中的字符串:
table[tableNumber] = strdup(name);
这是一个完整的修改后的程序:
#include <stdio.h>
#include <string.h>
int main() {
char *table[5] = { NULL, NULL, NULL, NULL, NULL };
char buffer[50];
char *number;
char *name;
int tableNumber;
for (int i = 0; i < 5; i++) {
if (!fgets(buffer, sizeof buffer, stdin))
break;
number = strtok(buffer, "-");
if (number == NULL) {
printf("empty line\n");
continue;
}
name = strtok(NULL, "-\n");
if (name == NULL) {
printf("no name after -\n");
continue;
}
tableNumber = atoi(number);
if (tableNumber < 0 || tableNumber >= 5) {
printf("invalid number: %d\n", tableNumber);
continue;
}
table[tableNumber] = strdup(name);
}
for (int i = 0; i < 5; i++) {
if (table[i])
printf("table %d = %s\n", i, table[i]);
}
for (int i = 0; i < 5; i++) {
free(table[i]);
}
return 0;
}
如果你的目标系统不支持strdup()
,使用这个:
#include <stdlib.h>
#include <string.h>
char *mystrdup(const char *s) {
size_t size = strlen(s) + 1;
char *p = malloc(size);
return (p != NULL) ? memcpy(p, s, size) : NULL;
}