在c数组索引问题中从串行端口读取

在c数组索引问题中从串行端口读取,c,arrays,serial-port,C,Arrays,Serial Port,我有一些c代码,它可以连续地从串行端口读入缓冲区,当它读取了100个字节时,它会使用函数log\u write()将它们写入websocket。 有些数据丢失了,所以我想我的行为是不明确的。代码有什么明显的错误吗 具体地说,在下面的几行中,我是否应该向rdlentotal添加1?是否覆盖了上次读取的最后一个字符 在读取最后一个字符后终止缓冲区是否也应该为null?我该怎么做 rdlen=read(fd_焦耳,&ibuf[rdlentotal],sizeof(ibuf)); rdlentotal+

我有一些c代码,它可以连续地从串行端口读入缓冲区,当它读取了100个字节时,它会使用函数
log\u write()
将它们写入websocket。 有些数据丢失了,所以我想我的行为是不明确的。代码有什么明显的错误吗

具体地说,在下面的几行中,我是否应该向
rdlentotal
添加1?是否覆盖了上次读取的最后一个字符

在读取最后一个字符后终止缓冲区是否也应该为null?我该怎么做

rdlen=read(fd_焦耳,&ibuf[rdlentotal],sizeof(ibuf));
rdlentotal+=rdlen/*跟踪读取的总字节数*/

int rdlen=0, rdlentotal = 0;
char ibuf[1024];

memset(&ibuf[0], 0, sizeof(ibuf)); /*clear the buffer*/

while (1) {

    /*read from serial port*/
    rdlen = read(fd_joule, &ibuf[rdlentotal], sizeof(ibuf));
    rdlentotal += rdlen; /*keep track of total bytes read*/

    if (rdlentotal > 100) { /*when you have 200 bytes write the websocket*/
        log_write("%s", &ibuf); /*write to websocket*/
        memset(&ibuf[0], 0, sizeof(ibuf)); /*clear buffer*/
        rdlentotal = 0; /*rest byte counter */
        rdlen = 0;
    }

    if (rdlen < 0) {
        fprintf(stderr, "rdlen les than 0\r\n");
    }

}

上述评论是正确的。为了进一步说明,您可能会通过覆盖超过ibuf的内存以及不可预测的行为和可能的崩溃来损坏堆栈

代码有什么明显的错误吗

是的,见下文

特别是在下面的行中,我是否应该在
rdlentotal
中添加1

没有

是否覆盖了上次读取的最后一个字符

没有

。。。在读取最后一个字符后终止缓冲区是否应该为null

是,如果
buf
被视为字符串。然而,由于输入中可能包含
'\0'
字节,因此更健壮的代码将
buf
视为字符数组,并将
buf
及其长度传递给日志函数。也看到

我该怎么做(null终止缓冲区)

见下文#2


代码至少存在以下问题:

  • 缓冲区溢出的可能性

    // rdlen = read(fd_joule, &ibuf[rdlentotal], sizeof(ibuf));
    rdlen = read(fd_joule, &ibuf[rdlentotal], sizeof(ibuf) - rdlentotal);
    
  • 假设
    log\u写入(“%s”和&ibuf)类似于
    printf()
    ,代码试图打印
    ibuf
    ,它可能不是字符串,也不一定以空字符结尾。想想如果第一次读取的长度是
    sizeof(ibuf)
    个字符,会发生什么。相反,请确保空格并附加一个空字符

    char ibuf[1024 + 1];  // add 1 here                   - 1 below
    ...
    rdlen = read(fd_joule, &ibuf[rdlentotal], sizeof ibuf - 1 - rdlentotal);
    ...
    ibuf[rdlentotal + rdlen] = '\0';  // Code is certain to have memory for the \0
    ...
    log_write("%s", &ibuf);  // The use of & here is likely not needed.
    
  • read()
    返回一个
    ssize\u t
    ,而不是
    int
    。使用该类型并在
    rdlentotal+=rdlen之前检查错误

    ssize_t rdlen = read(...
    if (rdlen == -1) {
      LOG("error reading serial port, rdlen less than 0\r\n");
      continue;
    }
    rdlentotal += rdlen;
    
  • 对数组长度使用
    size\u t
    int

    // int rdlentotal = 0;
    size_t rdlentotal = 0;
    
  • 次要:注释不反映代码

    // if (rdlentotal > 100) { /*when you have 200 bytes write the websocket*/
    if (rdlentotal > 100) { /*when you have more than 100 bytes write the websocket*/
    

  • read(fd_焦耳,&ibuf[rdlentotal],sizeof(ibuf))-->
    读取(fd_焦耳,&ibuf[rdlentotal],sizeof(ibuf)-rdlentotal)请告诉我们-字节流中可以有NUL吗?如果是这样的话,你已经崩溃了,正如chux在下面所暗示的那样。samsung gather:与其为你的问题添加答案的副本,不如1)复习2)将你的问题回滚到以前的版本。
    
    // int rdlentotal = 0;
    size_t rdlentotal = 0;
    
    // if (rdlentotal > 100) { /*when you have 200 bytes write the websocket*/
    if (rdlentotal > 100) { /*when you have more than 100 bytes write the websocket*/