C:删除新行/空终止输入字符串

标签 c arduino embedded

在 C 中,我使用串行库中的此方法:

int serialport_read_until(int fd, char* buf, char until, int buf_max, int timeout)
{
    char b[1];  // read expects an array, so we give it a 1-byte array
    int i=0;
    do { 
        int n = read(fd, b, 1);  // read a char at a time
        if( n==-1) return -1;    // couldn't read
        if( n==0 ) {
            usleep( 1 * 1000 );  // wait 1 msec try again
            timeout--;
            if( timeout==0 ) return -2;
            continue;
        }
#ifdef SERIALPORTDEBUG  
        printf("serialport_read_until: i=%d, n=%d b='%c'\n",i,n,b[0]); // debug
#endif
        buf[i] = b[0]; 
        i++;
    } while( b[0] != until && i < buf_max && timeout>0 );

    buf[i] = 0;  // null terminate the string
    return 0;
}

它将读取的字符串如下所示: “111\r\n”(后面有一个回车+换行符)

它正在 Arduino 中使用打印出来

serial.print("1");
serial.print("1");
serial.println("1");

使用serialport_read_until方法(字符直到为“\r\n”),我想确保正确读取整个缓冲区。

char* buf 最后看起来像下面哪一个?

1) 111\r\n

2) 111\r\n\0

3) 111\0

4) 111

在使用 sscanf 方法将字符串正确转换为整数之前,我需要弄清楚这部分,但我不确定使用哪个:

sscanf(buf, "%d\r\n", #num);sscanf(buf, "%d", #num);

此外,我是否应该将倒数第二行: buf[i] = 0; 更改为 buf[i-1] = 0;

最佳答案

在我看来,你应该期待 111\r\n\0 。请注意,条件b[0] != until递增 i 后检查,因此当收到换行符并退出循环时,i指向 \n 之后的下一个字节。然后b[i]=0在那里存储一个空字节。

请注意,此代码似乎有一个错误:如果 until从未收到字符,循环将运行直到 i == buf_max然后用空终止符再存储一个字节。所以总共buf_max+1存储字节,这意味着以下代码将出现缓冲区溢出:

char mybuf[123];
serialport_read_until(fd, buf, 'x', 123, 42);

除非文档说 buf_max应该比缓冲区的大小小一,这违反直觉并且容易出错,循环终止条件可能应该是 i+1 < buf_max或类似的东西。

此外,自 i在最后检查,即使进行此修复,如果您传入 buf_max == 0 ,代码仍将存储一个字节。 (但如果没有修复,它将存储两个字节)。所以这是另一个错误。

char b[1];声明和附带的评论也有点奇怪。简单地声明 char b; 会更惯用。然后通过 &bread() .

因此,如果这是您的代码,那么还有更多工作要做。如果是其他人的代码,如果这个函数可以表明质量,我会非常小心地使用这个库。

正在做buf[i-1]=0最后会避免溢出,但也意味着如果 until未接收到字符,接收到的最后一个字节将丢失。如果您使用 buf_max == 0 调用该函数,它也会中断。 。所以这不是你想要的。

如果您使用sscanf ,是否存在尾随空格的问题无关紧要; sscanf("%d")只会忽略它。您应该仔细阅读图书馆的 sscanf 文档。特别是,它处理空白的方式并不总是直观的。

关于C:删除新行/空终止输入字符串,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36183623/

相关文章:

c - 如果以下代码中没有 "volatile"关键字,编译器可以执行什么优化?

embedded - stm32f4 上的 I2C 从接收器

c++ - 如何在arduino上使函数返回字符串?

c# - 使用 .Net 写入 COM 端口

arduino - 什么是 rosidl_runtime_c__double__Sequence 类型?

c++ - 结构的 Hexdump 没有输出正确的信息

c - TI MSP430 中断源

c - 获取 ext2 镜像中的特定 inode (C)

C汇编语言ATT演练?

c++ - 为 C/C++ 设置 Windows 构建环境的最佳方法