我使用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] = '\0';
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);
}
这是针对Simple Studio IDE中的微控制器的。
我在emberAfPreMessageReceivedCallback中正确获得了有效载荷,并将其分成4部分并正确打印。
但是在将sceneName复制到gSceneTable数组后,我看到gSceneTable的所有元素中的最后一个sceneName带有gSceneTable [sceneTableNumber] = sceneName,我看到了“ p]”,其中gSceneTable [sceneTableNumber] = strdup(sceneName);
您的程序极不可能产生发布的输出。该代码段只处理一个字符串和char *table[5];
未初始化,所以打印从琴弦table[0]
,table[2]
,table[3]
和table[4]
具有不确定的行为。您已指定从文件中读取字符串,需要发布完整的程序才能进行精确而正确的分析。如果文件没有覆盖所有条目,则不初始化数组是一个问题,将无法分辨出哪些设置了,哪些没有设置。
假设您的程序从文件或标准输入中读取字符串,使用进行解析,则strtok
返回指向源字符串的指针,该字符串是您从文件中读取行的数组。因此,table[]
数组中的所有条目都指向该数组中的同一字节,这解释了您得到的输出:最后一行内容的5倍。
您应该复制存储在表中的字符串:
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;
}
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句