简体   繁体   English

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

[英]C++ Eclipse console encoding plain text as other characters

I have a C++ program running on an Intel Edison reading some GPS data from a serial port and echoing it back to the console. 我有一个英特尔爱迪生运行从一个串口读取GPS的一些数据的C ++程序和呼应回控制台。

That part is working fine, but when the strings are read in the console they have characters that shouldn't be there, like "¬é". 这部分工作正常,但是当琴弦在控制台读取他们的字符不应该在那里,像“¬é”。 I'm guessing that something is messed up with encoding in the Eclipse console/G++, and it thinks some of the readings are character codes. 我猜的东西是搞砸了与Eclipse控制台/ G ++编码,并认为一些读数是字符代码。

Here is some output from the Eclipse Console: 以下是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

And here is some of the output as read directly from the serial port on the Edison ( cat /dev/ttyMFD1 ): 这里是一些输出的直接从爱迪生(串口读取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

I tried all the encoding options available in the run configurations common tab, but they all produced stranger results, even Chinese characters! 我尝试了运行配置“公共”选项卡中所有可用的编码选项,但它们都产生了奇怪的结果,甚至是汉字!

The relevant code is char array[255]; 相关代码是char array[255]; to initialize the buffer, and then this to read the serial data into the buffer and output it into the console: 初始化缓冲区,然后将串行数据读入缓冲区并将其输出到控制台:

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

Given this 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

adding rn to represent the two characters of the CRLF that terminates a line of NMEA data that, and then just counting the number of characters between the garbage I get 添加rn代表CRLF的两个字符,该字符终止一行NMEA数据,然后仅计算我得到的垃圾之间的字符数

  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 characters 255个字符

Exactly one of these: 正是其中之一:

dev->read(array,255);

Cheap hack is to 廉价的黑客是为了

char array[256];

and then 接着

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

But I think you are better off with something like this: 但我认为您最好使用以下方法:

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

where 哪里

receiveUntil reads the incoming stream into array until it finds the end of the NMEA sentence then null terminates array and returns the number of bytes read or array is about to overflow, in which case it returns -1. receiveUntil将进入的流读入array直到找到NMEA句子的末尾,然后null终止array并返回读取的字节数或array即将溢出,在这种情况下,它返回-1。

discardUntil throws away everything until it finds the NMEA start character '$' discardUntil丢弃所有内容,直到找到NMEA起始字符“ $”

Bonus points for replacing receiveUntil with a function that resets array when it finds a $ so you don't miss any messages that weren't already corrupt. 带有将在找到$时重置array的函数来替换receiveUntil奖励点,因此您不会错过任何尚未损坏的消息。

Turns out it wasn't an issue with encoding. 事实证明,这与编码无关。 I started to realize it was something else when I tried to do the same thing with NodeJS, and got the same output back. 当我尝试使用NodeJS进行相同的操作并返回相同的输出时,我开始意识到这是另一回事。

I forgot that the correct way to read the output from this GPS module is to read the characters one at a time until you hit the newline terminator at the end of the line, and then work with it/log it to console. 我忘记了从此GPS模块读取输出的正确方法是一次读取一个字符,直到您击中行尾的换行符为止, 然后使用它/将其记录到控制台。

So my code then became: 所以我的代码变成了:

char array[255];
char c[1];
int i = 0;

while(true){
     dev->read(c,1);

     if(c[0] == '\n'){
         i = 0;

         std::cout<<"-> "<<array<<std::endl;

         char *begin = array;
         char *end = begin + sizeof(array);
         std::fill(begin, end, 0);
     }else{
         array[i] = c[0];
         ++i;
     }
}

Which now works perfectly :) 现在可以完美工作了:)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM