c++ 映射到无符号字符数组

问题描述 投票:0回答:3

我正在尝试从 openweathermap.org api 中提取天气图标,并使用 u8g2 库(Arduino IDE,C++11)将它们显示在 ESP32 驱动的 OLED 显示器上。

在openweathermap.org weather api中,16种天气定义为

const *char[]
"01d"
"01n"
"02d"

u8g2 库使用 unsigned char 数组来定义 XBM 位图格式的图标。我已经这样定义了所有图标:

static unsigned char icon01d[] = {
   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
   ...
}

可以通过以下方式在 OLED 上显示图标:

u8g2.drawXBMP( 96, 0, 32, 32, icon01d );

我想使用 std::map 将天气 api 中的字符串链接到指向图标的指针,例如:

map< string, unsigned char[]* > WEATHER_ICONS = { 
  { "01d", &icon01d },
  { "01n", &icon01n },
  ...
};

然后(在我的幻想中)能够显示适当的图标,如:

u8g2.drawXBMP( 96, 0, 32, 32, *WEATHER_ICONS[ weatherIcon ] );

with weatherIcon 是

const *char[]
投射到一个字符串。

我尝试了各种替代方法来设置地图:

std::map< std::string, <<variable reference>> > WEATHER_ICONS = { 
  { "01d", &icon01d },
  { "01n", &icon01n }
};

根据表格

<<variable reference>>
,我得到各种错误信息:

使用的变量引用 返回错误信息
unsigned char[128]*
template argument 2 is invalid
unsigned char[]*
template argument 2 is invalid
unsigned char*[128]
could not convert '{{"01d", (& icon01d)}, {"01n", (& icon01n)}}' from '<brace-enclosed initializer list>' to 'std::map<std::__cxx11::basic_string<char>, unsigned char* [128]>'
unsigned char*[]
could not convert '{{"01d", (& icon01d)}, {"01n", (& icon01n)}}' from '<brace-enclosed initializer list>' to 'std::map<std::__cxx11::basic_string<char>, unsigned char* []>'
unsigned char**
could not convert '{{"01d", (& icon01d)}, {"01n", (& icon01n)}}' from '<brace-enclosed initializer list>' to 'std::map<std::__cxx11::basic_string<char>, unsigned char**>'

没有一条错误信息对我很有帮助。看来我已经到了“c 指针地狱”。

我在 stackoverflow 上看到关于定义指向指针数组的指针的建议,例如

unsigned char**
但我缺少足够的细节来让它工作。

什么是正确的解决方案?

作为解决方法,我已经实现了它:

      if     ( strcmp( weatherIcon, "01d" )==0 ) u8g2.drawXBMP( 96, 0, 32, 32, icon01d );
      else if( strcmp( weatherIcon, "01n" )==0 ) u8g2.drawXBMP( 96, 0, 32, 32, icon01n );
      else if( strcmp( weatherIcon, "02d" )==0 ) u8g2.drawXBMP( 96, 0, 32, 32, icon02d );
      else if( strcmp( weatherIcon, "02n" )==0 ) u8g2.drawXBMP( 96, 0, 32, 32, icon02n );
      else if( strcmp( weatherIcon, "03d" )==0 ) u8g2.drawXBMP( 96, 0, 32, 32, icon03d );
      else if( strcmp( weatherIcon, "03n" )==0 ) u8g2.drawXBMP( 96, 0, 32, 32, icon03n );
      else if( strcmp( weatherIcon, "04d" )==0 ) u8g2.drawXBMP( 96, 0, 32, 32, icon04d );
      else if( strcmp( weatherIcon, "04n" )==0 ) u8g2.drawXBMP( 96, 0, 32, 32, icon04n );
      else if( strcmp( weatherIcon, "09d" )==0 ) u8g2.drawXBMP( 96, 0, 32, 32, icon09d );
      else if( strcmp( weatherIcon, "09n" )==0 ) u8g2.drawXBMP( 96, 0, 32, 32, icon09n );
      else if( strcmp( weatherIcon, "11d" )==0 ) u8g2.drawXBMP( 96, 0, 32, 32, icon11d );
      else if( strcmp( weatherIcon, "11n" )==0 ) u8g2.drawXBMP( 96, 0, 32, 32, icon11n );
      else if( strcmp( weatherIcon, "13d" )==0 ) u8g2.drawXBMP( 96, 0, 32, 32, icon13d );
      else if( strcmp( weatherIcon, "13n" )==0 ) u8g2.drawXBMP( 96, 0, 32, 32, icon13n );
      else if( strcmp( weatherIcon, "50d" )==0 ) u8g2.drawXBMP( 96, 0, 32, 32, icon50d );
      else if( strcmp( weatherIcon, "50n" )==0 ) u8g2.drawXBMP( 96, 0, 32, 32, icon50n );

有效,但不是很优雅。

c++ pointers esp32 stdmap
3个回答
0
投票

在 C 和 C++ 中,评估数组的名称会产生指向数组中第一个值的指针。

你的

static unsigned char icon01d[]
真的是变相的
unsigned char *
。所以:

map< string, unsigned char* > WEATHER_ICONS = { 
  { "01d", icon01d },
  { "01n", icon01n },
  ...
};

从您的问题中不清楚是否有必要知道每个此类数组的大小。如果所有这些

unsigned char
数组的大小都相同,那么就可以了。否则,也许,你可以存储两者,吐出这样的东西:

map< string, tuple<unsigned char*, size_t> > WEATHER_ICONS = { 
  { "01d", {icon01d, sizeof(icon01d)} },
  { "01n", {icon01n, sizeof(icon01n)} },
  ...
};

0
投票

在您对

drawXBMP
的第一个示例调用中,您有:

u8g2.drawXBMP(96, 0, 32, 32, icon01d);

那么,在这种情况下,

icon01d
是什么?由于您传递的是不带索引的数组名称,因此您实际上传递的是指向数组中第一个元素的指针。在这种情况下,它是一个
unsigned char*
.

当你声明你的地图时,这就是你应该使用的。像这样:

map<string, unsigned char*> WEATHER_ICONS = {

然后你应该像这样调用

drawXBMP

u8g2.drawXBMP(96, 0, 32, 32, WEATHER_ICONS[weatherIcon]);

0
投票

看起来解决方案是:

std::map< std::string, unsigned char (*)[128] > WEATHER_ICONS = { 
  { "01n", & icon01n },
  { "02d", & icon02d },

别问我怎么知道的..

感谢两位尝试回答问题,如果问题不清楚,我很抱歉。

© www.soinside.com 2019 - 2024. All rights reserved.