我编写了函数readChar()
,它旨在逐个读取我的WiFi模块发送的字符(函数已经公布)并将它们传递给越来越大的char缓冲区。当检测到char *endChar
(多个字符)或timedRead()
返回的字符数超过size_t length
时,该函数应停止。
我有几个问题:
1 /。我不理解语法(在Arduino Stream库中找到):
*buffer++ = (char)c;
你能解释数组buffer
是如何被填充的吗?
为什么buffer[index] = (char)c;
在这里不起作用?
2 /。我想在循环中比较buffer
和endChar
,可能使用strcmp(buffer,endChar)
(也许有更好的方法)。但这似乎不起作用。实际上,当打印我的char *buffer
的ASCII值时,似乎从缓冲区的末尾开始递增。例如。:
那么进行这种比较的最佳方法是什么?
插入循环中的代码:
_dbgSerial->println("buffer");
for (int i = 0; i < 32; i++){
_dbgSerial->print(buffer[i], DEC);
_dbgSerial->print(",");
}
_dbgSerial->println("");
打印:
缓冲
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 ,0,0,0,0,0,0,0,13, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,13,10, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,13,10,13, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,13,10,13,10, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,13,10,13,10,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,13,10,13,10,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 13,10,13,10,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,13, 10,13,10,0,0,0,0,
这是函数readChar()
:
size_t Debugwifi::readChar(char *endChar, char *buffer, size_t length) {
if (length < 1) return 0;
size_t index = 0;
while (index < length) {
int c = timedRead();
if (c < 0 ) break;
//buffer[index] = (char)c;
*buffer++ = (char)c;
_dbgSerial->println("buffer");
for (int i = 0; i < 32; i++){
_dbgSerial->print(buffer[i], DEC);
_dbgSerial->print(",");
}
_dbgSerial->println("");
if (strcmp(buffer,endChar)==0) {
break;
_dbgSerial->println("brk");}
index++;
}
return index;
}
答案 0 :(得分:2)
*buffer++ = (char) c;
首先将 c 的值写入缓冲区当前指向的内容。 然后它递增缓冲区
这也是您打印缓冲区的循环不起作用的原因。 在刚刚填满的位置开始从位置开始打印。
这也是你的strcmp不起作用的原因。它实际上并没有比较你填充缓冲区的内容。它将内容与已填写的内容进行比较。
如果您希望打印代码正常工作,您应该在循环之前保存 buffer 的初始值;
const char * buffer_start = buffer; 然后在打印代码中使用它而不是缓冲区。
答案 1 :(得分:2)
正如Rickard所解释的那样,*buffer++ = (char)c;
是指向指针所指向的内存中的一个字符,然后递增指针。
但是,您的函数存在很多问题 - 您将未设置的内存与*endChar
进行比较。我建议:
size_t Debugwifi::readChar(const char * const endStr, // const pointer to const.
char * const buffer, const size_t length) {
if (length < 1) return 0;
const size_t endLen = strlen(endStr);
for (size_t index = 0; index < length; index++) {
const int c = timedRead();
if (c < 0 ) break;
buffer[index] = (char)c;
// Debug
_dbgSerial->println("buffer");
for (size_t i = 0; i < length; i++){ // Better to use size_t here,
// and compare against length not 32
_dbgSerial->print(buffer[i], DEC);
_dbgSerial->print(",");
}
_dbgSerial->println("");
// Finished?
if (index >= endLen) {
if (memcmp(&buffer[index-endLen], endStr, endLen)==0) {
_dbgSerial->println("brk"); // Must do this *before* "break"!
break;
}
}
}
return index;
}
我添加了很多const
个。很难有太多。
重点是,一旦你读完了足够的字符,就可以开始将你读过的最后一个字符与结束标记进行比较。
请注意,此函数不会删除结束标记,如果传递一个32字节的零填充数组并且它读取32个字符,则结果将 NOT 零终止。
最后,我将参数名称更改为endStr
,因为我原以为endChar
是指向单个字符的指针 - 而不是以NUL结尾的字符串。