英文:
Converting a UDP Payload -> Struct -> Long, Lat in decimal degree (12.41N, 2.40E) (im a junior < 1 year) c++
问题
I will only provide translations for the code-related portions of your text. Here's the translated code:
第一次在这里提问,请容忍我如果问题不够好。
Visual Studio。
C++。
UDP。
我接收到一个UDP数据包,将其存储在一个char缓冲区中。
我有一个按字节对齐的结构体,用来将缓冲区拆分成结构体的各个元素。
我需要从结构体中获取经度和纬度,并输出到控制台,但结果看起来不正确。
当我使用Wireshark查看UDP数据包时,我可以看到经度和纬度,并知道它们代表的值:
3FA24690119236AC -> 12.41890000(N)
3FCBBE7C9C146695 -> 2.04515000(E)
我正在使用的经度和纬度的数据类型是unsigned long long。
我无法弄清楚如何从3FCBBE7C9C146695转换为12.41890000,考虑到它可能是小端字节序。
是否有人可以友善地解释我应该做什么,以初学者的思维方式,并演示一些代码。
我明白你不会有UDP数据包。
这是我希望看到的理解(即使我是否正确理解过程也不确定)。
```cpp
char buffer[] = { '3F', 'A2', '46', '90', '11', '92', '36', 'AC' };
struct payload { unsigned long long lat; };
payload p;
std::memcpy(&p, buffer, sizeof(p));
.... 转换为十进制度数
printf("Lat: %llu\n", p.lat);
再次说明,我是新手,希望学习!
非常感谢提前的帮助,如果需要改进问题的格式,请告诉我!
```cpp
p.lat = ntohll(p.lat);
p.lat = ntohd(p.lat);
尝试了这些,并将数据类型更改为double、long、int64、uint64,但现在感到困惑。
更多信息....
我想要看到的输出是12.41250000°N 2.43520000°E。
仅有UDP数据包(lat和lon是唯一感兴趣的部分)
39000000000000000000000000030000006500000059ffffffffffffffff41d9205f3f80000000000001c0a801b73fcbbad397da94bd3fa5c2db1fc191f800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000017ae
文档说明这些(lat、lon)应该是
8字节双精度浮点数(接受的值:-π/2 - π/2(弧度))用于纬度
8字节双精度浮点数(接受的值:-π - π(弧度))用于经度
现在使用unsigned char数组(UDP -> 结构体)
然后
double result;
std::memcpy(&result, p.lat, sizeof(double));
std::cout << "Lat: " << result << std::endl;
得到:Lat: -4.74162e-12
打印出数组:
3fa5c2db1fc191f8
所以似乎数组包含了我在Wireshark中看到的正确十六进制值。
请尽量“简化”它,因为我真的想了解我遇到的问题,而不仅仅是解决它。
再次感谢!
<details>
<summary>英文:</summary>
First ever time asking a question on here so go easy on me if its not up to par.
Visual Studio.
C++.
UDP.
I receive a UDP payload which I store in a char buffer.
I have a struct which is byte-aligned to split the buffer into the elements of the struct.
I need to get the lon, lat from the struct and cout to console but it doesnt look correct.
When i wireshark the UDP payload i can see the lon, lat and i know the values it represents:
3FA24690119236AC -> 12.41890000 (N)
3FCBBE7C9C146695-> 2.04515000 (E)
The data type for the lon, lat im using is unsigned long long.
I cannot work out how to go from 3FCBBE7C9C146695 -> 12.41890000 bearing in mind its probably little-endian.
Could someone be so kind as to explain what I should be doing, in a <1 year juniors mindset and demonstrate with some code.
I understand you wont have the UPD payload.
This is my understanding of what I would like to see (if I even understand the process correctly).
char buffer[] = { '3F', 'A2', '46', '90', '11', '92', '36', 'AC'};
struct payload { unsigned long long lat; };
payload p;
std::memcpy(&p, buffer, sizeof(p));
.... convert to its dec degree
printf("Lat: %llu\n", p.lat);
Again I am a newbie and wish to learn!
Many thanks in advance, also let me know if I need to format my question better!
`p.lat = ntohll(p.lat);`
`p.lat = ntohd(p.lat);
`
Tried these and changing the data type to double, long, int64, uint64 but I'm chasing my tail now.
More Info....
12.41250000°N 2.43520000°E is the output i want to see.
UDP payload only (**lat**, *lon* are the only parts of interest)
39000000000000000000000000030000006500000059ffffffffffffffff41d9205f3f80000000000001c0a801b7**3fcbbad397da94bd***3fa5c2db1fc191f8*000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000017ae
Documentation states these (lat, lon) should be
8 byte double (accepted values: -π/2 - &pi/2; (Radians)) for lat
8 byte double (accepted values: -π - π (Radians) for lon
Now using `unsigned char arrays (UPD -> Struct)`
then
double result;
std::memcpy(&result, p.lat, sizeof(double));
std::cout << "Lat: " << result << std::endl;
gives: Lat: -4.74162e-12
Printing out the array:
3fa5c2db1fc191f8
so it seems the array hold the correct hex i see in wireshark.
Please do try and 'dumb it down' as I really would like to understand the issue i have and not just to solve it.
Thanks Again
</details>
# 答案1
**得分**: 0
Clue1: 弧度
Clue2: 没有什么能阻止你尝试将角度和弧度的双精度转换成char[],看看它给出了什么结果。
事实证明,它转换的是弧度,而不是角度版本的角度。至少在我的电脑上,你还必须反转字节的顺序。(但我不知道这是多么普遍的现象。)
```cpp
#include <iostream>
#include <cstring>
#include <algorithm>
#include <cmath>
using namespace std;
const double PI = 4.0 * atan( 1.0 );
double decode( unsigned char *buffer, int n )
{
reverse( buffer, buffer + n);
double result;
memcpy( &result, buffer, n );
return result * 180.0 / PI;
}
int main()
{
const int N = sizeof( double );
unsigned char buffer1[N] = { 0x3f, 0xcb, 0xba, 0xd3, 0x97, 0xda, 0x94, 0xbd };
unsigned char buffer2[N] = { 0x3f, 0xa5, 0xc2, 0xdb, 0x1f, 0xc1, 0x91, 0xf8 };
cout << "Latitude: " << decode( buffer1, N ) << '\n';
cout << "Longitude: " << decode( buffer2, N ) << '\n';
}
输出:
纬度:12.4125
经度:2.4352
英文:
Clue1: RADIANS
Clue2: There's nothing stopping you trying the degrees and radians double to char[] conversion and seeing what it gives you.
It turns out that it converts the radians, rather than degrees version of the angle. On my PC at least you also have to reverse the order of bytes. (But I don't know how universal that is.)
#include <iostream>
#include <cstring>
#include <algorithm>
#include <cmath>
using namespace std;
const double PI = 4.0 * atan( 1.0 );
double decode( unsigned char *buffer, int n )
{
reverse( buffer, buffer + n);
double result;
memcpy( &result, buffer, n );
return result * 180.0 / PI;
}
int main()
{
const int N = sizeof( double );
unsigned char buffer1[N] = { 0x3f, 0xcb, 0xba, 0xd3, 0x97, 0xda, 0x94, 0xbd };
unsigned char buffer2[N] = { 0x3f, 0xa5, 0xc2, 0xdb, 0x1f, 0xc1, 0x91, 0xf8 };
cout << "Latitude: " << decode( buffer1, N ) << '\n';
cout << "Longitude: " << decode( buffer2, N ) << '\n';
}
Output:
Latitude: 12.4125
Longitude: 2.4352
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论