在函数内填充和比较char *

时间:2017-01-11 08:33:45

标签: c++ pointers arduino

我编写了函数readChar(),它旨在逐个读取我的WiFi模块发送的字符(函数已经公布)并将它们传递给越来越大的char缓冲区。当检测到char *endChar(多个字符)或timedRead()返回的字符数超过size_t length时,该函数应停止。

我有几个问题:

1 /。我不理解语法(在Arduino Stream库中找到):

*buffer++ = (char)c;

你能解释数组buffer是如何被填充的吗? 为什么buffer[index] = (char)c;在这里不起作用?

2 /。我想在循环中比较bufferendChar,可能使用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;
}

2 个答案:

答案 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结尾的字符串。