C++串口接收数据异常:多出ffffff字符、缺前导0偶发变值,求代码问题排查
问题1:输出显示异常(ffffff前缀、丢失前导0)
- 核心原因是
input变量的类型为默认的有符号char:当字节数值大于0x7F(十进制127)时,强转为int会触发符号扩展,高位全部补1,最终输出就会带上ffffff前缀。 - 丢失前导0是因为
cout默认输出十六进制时不会自动补位,单字节的0x0E会直接输出为e。 - 修复方法:
- 将
input数组定义为unsigned char类型,避免符号扩展 - 配置
cout的十六进制输出格式,强制输出2位、补前导0,示例代码:
- 将
#include <iomanip> // 需提前引入该头文件 // 假设input已定义为 unsigned char input[14]; cout << hex << setw(2) << setfill('0') << uppercase << (int)input[i] << endl;
问题2:偶发数据错误的代码逻辑缺陷
你的串口读取逻辑存在两个明显错误,是导致数据偶发错乱的核心原因:
- 未判断
ReadFile返回的实际读取字节数bytesRead:串口是流式设备,ReadFile不会保证一次读完你请求的14字节,可能只返回1~13个字节,你直接循环读取14个位置,剩下的位置会读取到栈上的旧脏数据,自然会出现数值错误。 - 未校验串口事件触发的原因:你需要提前确保
eventMask已经配置为EV_RXCHAR(收到字符触发),否则可能在非收到数据的场景下误触发读取逻辑。 - 修复方法:
累加读取到的字节数,直到凑够14字节再处理,示例逻辑:
int totalNeed = 14; int alreadyRead = 0; unsigned char input[14] = {0}; if (WaitCommEvent(hSerial, &eventMask, NULL)) { if (eventMask & EV_RXCHAR) { // 确认是收到数据的事件 while (alreadyRead < totalNeed) { DWORD bytesRead = 0; if (ReadFile(hSerial, input + alreadyRead, totalNeed - alreadyRead, &bytesRead, NULL) == 0) { cout << "error reading file\n"; break; } alreadyRead += bytesRead; } // 凑够14字节后再输出 for (int i = 0; i < 14; i++) { cout << hex << setw(2) << setfill('0') << uppercase << (int)input[i] << endl; } } } else { cout << "error waiting for comm event\n"; }
内容的提问来源于stack exchange,提问作者shidrang
相关产品推荐
相关产品推荐

