【发布时间】:2018-03-10 00:54:17
【问题描述】:
我在尝试用字符串结构填充数组时遇到问题。可能,我在使用 Arduino 上的指针或内存分配规则时缺少一些基本的东西。
在下面查看我的代码。
要填充的数据结构:
struct SMSData {
String id;
String status;
String from;
String date;
String text;
};
字符串解析例程:
SMSData* readSMS(String reply) {
debugSerial.println(reply);
// declare a pointer to result array
SMSData* smsArray = NULL;
const String startPattern = F("+CMGL: ");
int index = -1;
// calculate result array length
byte count = 0;
do {
index = reply.indexOf(startPattern, (index + 1));
if(index < 0) {
break;
}
count++;
} while(true);
if(count == 0) {
return NULL;
}
debugSerial.println(count);
// allocate memory to store result array
smsArray = malloc(count * sizeof(SMSData*));
if(smsArray == NULL) {
return NULL;
}
// start parsing input String
index = reply.indexOf(startPattern);
int fromIndex = 0;
while(true) {
debugSerial.println();
if(index < 0) {
break;
}
// init data for the next element of result array
SMSData smsData = {"", "", "", "", ""};
// start filling result array element
// get id
fromIndex = index + startPattern.length();
index = reply.indexOf(F(","), fromIndex);
smsData.id = reply.substring(fromIndex, index);
debugSerial.println(smsData.id);
// get status
fromIndex = reply.indexOf(F("\""), index) + 1;
index = reply.indexOf(F("\""), fromIndex);
smsData.status = reply.substring(fromIndex, index);
debugSerial.println(smsData.status);
// get phone
fromIndex = reply.indexOf(F("\""), index + 1) + 1;
index = reply.indexOf(F("\""), fromIndex);
smsData.from = reply.substring(fromIndex, index);
debugSerial.println(smsData.from);
// get date
fromIndex = reply.indexOf(F("\""), index + 1) + 1;
index = reply.indexOf(F("\""), fromIndex);
smsData.date = reply.substring(fromIndex, index);
debugSerial.println(smsData.date);
// get text
fromIndex = index + 1;
index = reply.indexOf(startPattern, fromIndex);
if(index < 0) {
smsData.text = reply.substring(fromIndex);
} else {
smsData.text = reply.substring(fromIndex, index);
}
smsData.text.trim();
debugSerial.println(smsData.text);
// add filled element to result array
smsArray[count - 1] = smsData;
}
return smsArray;
}
输出解析数据:
SMSData* smsArray = readSMS(reply);
int count = sizeof(smsArray);
debugSerial.print(F("SMS count:"));
debugSerial.println(count);
for(int i = 0; i < count; i++) {
SMSData smsData = smsArray[i];
debugSerial.print(F("id: "));
debugSerial.println(smsData.id);
debugSerial.print(F("status: "));
debugSerial.println(smsData.status);
debugSerial.print(F("from: "));
debugSerial.println(smsData.from);
debugSerial.print(F("date: "));
debugSerial.println(smsData.date);
debugSerial.print(F("text: "));
debugSerial.println(smsData.text);
}
free(smsArray);
要解析的虚拟字符串:
String reply = "+CMGL: 1,\"REC READ\",\"+123456789012\",,\"2017/09/26,18:31:25+03\"\r\nHi\r\n+CMGL: 2,\"REC READ\",\"+123456789012\",,\"2017/09/26,18:34:25+03\"\r\nHello\r\n";
当我运行草图时,它的输出通常不同,但总是损坏和不完整,例如
+CMGL: 1,"REC READ","+123456789012",,"2017/09/26,18:31:25+03"
Hi
+CMGL: 2,"REC READ","+123456789012",,"2017/09/26,18:34:25+03"
Hello
2
1
REC READ
+12345678905+03 017/09/26,18:31:25+03
Hi
2
REC REA
根据输出,您可以看到,它会注销整个输入字符串,开始解析它,经历第一次循环迭代(混合来自结构字段的字符串),再次开始第二次迭代,用大量混合的字符串填充结构然后中途停止响应。
目前我认为除了内存分配问题之外没有其他原因导致这种行为,但我无法找出我做错了什么。
感谢您的帮助。
【问题讨论】:
-
String和F(...)的定义是什么? -
@Yunnosch String 是标准的 Arduino 数据类型(描述 - arduino.cc/en/Reference/StringObject,源 - github.com/arduino/Arduino/blob/master/hardware/arduino/avr/…),F 是用于将字符串值存储在闪存中的宏(请参见相同的头文件进行定义) .
-
reply是一个字符串变量,在我的帖子中看到它的声明和初始化。 -
除了查看 smsArray 的大小(它始终是 4,作为指针)之外,您还需要找到条目的数量。指向的分配内存的大小在解析器函数之外是未知的。
-
smsArray = malloc(count * sizeof(SMSData*));正在为count指向SMSData的指针分配空间,这不是您想要的实际数组。应该是smsArray = malloc(count * sizeof *smsArray);。
标签: c++ string struct arduino malloc