C++ Eclipse 控制台将纯文本编码为其他字符

标签 c++ eclipse g++ intel-edison

我有一个在 Intel Edison 上运行的 C++ 程序,它从串行端口读取一些 GPS 数据并将其回显到控制台。

那部分工作正常,但是当在控制台中读取字符串时,它们包含不应该存在的字符,例如“¬é”。我猜 Eclipse 控制台/G++ 中的编码有些困惑,它认为一些读数是字符代码。

这是 Eclipse 控制台的一些输出:

$GPVTG,,T,,M,0.041,N,0.075,K,A*24
$GPGGA,225153.00,5206.75433,N,12206.88881,W,1,10,1.03,582.1,M,-15.6,M,,*6F
$GPGSA,A,3,32,02,12,14,24,06,03,19,17,25,,,1.84,1.03,1.53*05
$GPGSV,3,1,11,¬é­N
-> 02,51,176,30,03,10,027,17,06,60,088,33,12,68,295,36*79
$GPGSV,3,2,11,14,10,316,30,17,20,072,27,19,45,069,40,24,36,215,35*7E
$GPGSV,3,3,11,25,29,301,28,29,05,254,,32,07,305,33*40
$GPGLL,5206.75433,N,12206.88881,W,225153.00,A,A*78
.53*05
$GPGSV,3,1,11,¬é­N

下面是一些直接从 Edison 串口读取的输出 (cat/dev/ttyMFD1):

$GPVTG,,T,,M,0.048,N,0.090,K,A*26
$GPGGA,225407.00,5206.75339,N,12206.88816,W,1,10,1.02,584.2,M,-15.6,M,,*6C
$GPGSA,A,3,32,02,12,14,24,06,03,19,17,25,,,1.80,1.02,1.49*0B
$GPGSV,3,1,11,02,52,176,15,03,10,026,20,06,59,086,29,12,69,295,41*76
$GPGSV,3,2,11,14,09,316,29,17,19,072,29,19,44,070,34,24,35,215,32*74
$GPGSV,3,3,11,25,30,301,29,29,06,254,,32,06,304,17*4C
$GPGLL,5206.75339,N,12206.88816,W,225407.00,A,A*7F
$GPRMC,225408.00,A,5206.75337,N,12206.88814,W,0.058,,170616,,,A*6F

我尝试了运行配置公共(public)选项卡中可用的所有编码选项,但它们都产生了奇怪的结果,甚至是汉字!

相关代码是char array[255];初始化缓冲区,然后将串口数据读入缓冲区并输出到控制台:

while(true){
    dev->read(array,255);
    std::cout<<"-> "<<array<<std::endl;
}

最佳答案

给定这个 block :

-> 02,51,176,30,03,10,027,17,06,60,088,33,12,68,295,36*79
$GPGSV,3,2,11,14,10,316,30,17,20,072,27,19,45,069,40,24,36,215,35*7E
$GPGSV,3,3,11,25,29,301,28,29,05,254,,32,07,305,33*40
$GPGLL,5206.75433,N,12206.88881,W,225153.00,A,A*78
.53*05
$GPGSV,3,1,11,¬é­N

添加 rn 来表示终止一行 NMEA 数据的 CRLF 的两个字符,然后只计算我得到的垃圾之间的字符数

  0123456789ABCDEF
0 02,51,176,30,03,
1 10,027,17,06,60,
2 088,33,12,68,295
3 ,36*79rn$GPGSV,3
4 ,2,11,14,10,316,
5 30,17,20,072,27,
6 19,45,069,40,24,
7 36,215,35*7Ern$G
8 PGSV,3,3,11,25,2
9 9,301,28,29,05,2
A 54,,32,07,305,33
B *40rn$GPGLL,5206
C .75433,N,12206.8
D 8881,W,225153.00
E ,A,A*78rn.53*05r
F n$GPGSV,3,1,11,

255 个字符

恰好是其中之一:

dev->read(array,255);

廉价黑客是

char array[256];

然后

dev->read(array,sizeof(array)-1);
array[sizeof(array)-1] = '\0';

但我认为你最好用这样的东西:

int len = receiveUntil(array,sizeof(array), "\r\n")
if (len >= 0)
{
    // checksum and parse
}
discardUntil ("$");

在哪里

receiveUntil 将传入流读入array,直到找到 NMEA 语句的结尾然后 null 终止 array 并返回字节数read 或 array 即将溢出,在这种情况下它返回 -1。

discardUntil 丢弃所有内容,直到找到 NMEA 起始字符“$”

receiveUntil 替换为在找到 $ 时重置 array 的函数的奖励积分,这样您就不会错过任何未收到的消息'已经腐败了。

关于C++ Eclipse 控制台将纯文本编码为其他字符,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37891573/

相关文章:

c++ - 为什么在 C++ 中会发生这种情况?

c++ - "Member is private"虽然我不从外部访问它,但在使用尾随返回类型时

c++ - 编译程序以在 DOS 模式下运行

c++ - 我应该在公共(public)接口(interface)的结构中将相关参数分组吗?

java - 如何在android eclipse中使用单击按钮实现多个操作?

c++ - 我无法在不违反 C++ 扩展规则的情况下创建匹配的构造函数

c++ - 非成员(member)运营商作为外国类(class)的私有(private)成员(member)

android - Eclipse 的 Tomcat 插件

java - 从教程中实现 Android TimePicker - Source Force Closes

使用 <filesystem> 库的 C++ 程序在 Windows 上什么都不做