使用 String** 指针访问 String 数组元素的问题
Problems in using String** pointer for access elemnts of String array
这是一个在MCU中使用字体的程序。我有4个文件。 'zar.h' 和 'zar.cpp' 包含一种字体的数据。 'font.h' 和 'font.cpp' 包含动态设置字体的指针和函数。指针有很多问题。当访问“XB_Zar_name”数组元素时,通过“uni_name[i]”指针,MCU dos reset's。另一个问题是计算“XB_Zar_name”字符串数组中的字符串。修复这些错误后肯定会出现其他错误。请帮助我。
zar.h
/*v*/extern const unsigned char XB_Zar_118[];
/*w*/extern const unsigned char XB_Zar_119[];
/*x*/extern const unsigned char XB_Zar_120[];
/*y*/extern const unsigned char XB_Zar_121[];
/*z*/extern const unsigned char XB_Zar_122[];
extern char XB_Zar_width[];
extern const unsigned char* XB_Zar_addr[];
extern String XB_Zar_name[];
zar.cpp
/*v*/ const unsigned char XB_Zar_118[] PROGMEM ={255,255,254,255,63,255};
/*w*/ const unsigned char XB_Zar_119[] PROGMEM ={255,127,255,254,255,5};
/*x*/ const unsigned char XB_Zar_120[] PROGMEM ={215,215,23,254,255,127};
/*y*/ const unsigned char XB_Zar_121[] PROGMEM ={255,127,25,254,255,9};
/*z*/ const unsigned char XB_Zar_122[] PROGMEM ={255,243,239,254,215,19};
char XB_Zar_width[]= {2,2,2,2,2};
const unsigned char* XB_Zar_addr[] = {XB_Zar_118,XB_Zar_119,XB_Zar_120,XB_Zar_121,XB_Zar_122};
String XB_Zar_name[] = {"۰","۱","۲","۳","۴","۵"};
font.h
#pragma once
#include "zar.h"
extern unsigned char *char_addr;
extern unsigned int *char_width;
extern String **uni_name;
extern void setFont(byte fontNumber);
extern int getGliphData(String *uniChar, int *index, int *width);
font.cpp
#include "font.h"
unsigned char *char_addr = NULL;
unsigned int *char_width = NULL;
String **uni_name = NULL;
//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
void setFont(byte fontNumber)
{
switch (fontNumber)
{
case 0:
char_addr = (unsigned char *)(XB_Zar_addr);
*uni_name = XB_Zar_name;
char_width = (unsigned int *)XB_Zar_width;
break;
default:
char_addr = (unsigned char *)XB_Zar_addr;
break;
}
}
//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
int getGliphData(String *uniChar, int* index, int* charWidth)
{
Serial.println("uniChar data= "+*uniChar);
Serial.println("uni_name[i]= "+*uni_name[0]);// <---this resets the mcu
int countOfUniChars = sizeof(uni_name) / sizeof(String*);
for (int i = 0; i < countOfUniChars ; i++)
{
if (*uniChar == *uni_name[i])
{
*index = i;
*charWidth = char_width[i];
return i;
}
}
return -1;
}
在 getGliphData()
内部,uni_name
只是一个指针,因此您试图用来计算 countOfUniChars
的 sizeof()
技巧根本行不通(那里在 Whosebug 上有很多关于那个问题的问题。
因此,要么在存储数组指针的同时将数组长度存储到另一个全局变量中,要么用哨兵值(在本例中为空字符串)终止每个数组,然后循环遍历数组直到你到达哨兵。
此外,当 String*
指针就足够时,无需使用 String**
指针,因为您仅遍历 1 个 String
数组。如果您遍历指向 String
数组的指针数组,那么 String**
会更有意义。
此外,我看到的另一个问题是 XB_Zar_width[]
和 XB_Zar_addr[]
只有 5 个元素,但 XB_Zar_name[]
有 6 个元素,而 getGliphData()
正在尝试遍历 XB_Zar_name[]
使用其索引访问 XB_Zar_width[]
和 XB_Zar_addr[]
的元素,这显然不适用于第 6 个元素。
话虽这么说,但试试更像这样的东西:
// zar.h
/*v*/extern const unsigned char XB_Zar_118[];
/*w*/extern const unsigned char XB_Zar_119[];
/*x*/extern const unsigned char XB_Zar_120[];
/*y*/extern const unsigned char XB_Zar_121[];
/*z*/extern const unsigned char XB_Zar_122[];
extern const unsigned int XB_Zar_width[];
extern const unsigned char* XB_Zar_addr[];
extern const String XB_Zar_name[];
extern const int XB_Zar_name_len;
//zar.cpp
/*v*/ const unsigned char XB_Zar_118[] PROGMEM ={255,255,254,255,63,255};
/*w*/ const unsigned char XB_Zar_119[] PROGMEM ={255,127,255,254,255,5};
/*x*/ const unsigned char XB_Zar_120[] PROGMEM ={215,215,23,254,255,127};
/*y*/ const unsigned char XB_Zar_121[] PROGMEM ={255,127,25,254,255,9};
/*z*/ const unsigned char XB_Zar_122[] PROGMEM ={255,243,239,254,215,19};
const unsigned int XB_Zar_width[] = {2, 2, 2, 2, 2, 0}; // TODO: fix the 6th element!
const unsigned char* XB_Zar_addr[] = {XB_Zar_118, XB_Zar_119, XB_Zar_120, XB_Zar_121, XB_Zar_122, NULL}; // TODO: fix the 6th element!
const String XB_Zar_name[] = {"۰", "۱", "۲", "۳", "۴", "۵"}; // TODO: remove the 6th element?
const int XB_Zar_name_len = sizeof(XB_Zar_name)/sizeof(XB_Zar_name[0]);
//font.h
#pragma once
#include "zar.h"
extern const unsigned char **char_addr;
extern const unsigned int *char_width;
extern const String *uni_name;
extern int uni_name_len;
extern void setFont(byte fontNumber);
extern int getGliphData(const String &uniChar, int *index, int *width);
//font.cpp
#include "font.h"
const unsigned char **char_addr = NULL;
const unsigned int *char_width = NULL;
const String *uni_name = NULL;
int uni_name_len = 0;
//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
void setFont(byte fontNumber)
{
switch (fontNumber)
{
case 0:
char_addr = XB_Zar_addr;
char_width = XB_Zar_width;
uni_name = XB_Zar_name;
uni_name_len = XB_Zar_name_len;
break;
default:
char_addr = XB_Zar_addr;
char_width = XB_Zar_width;
break;
}
}
//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
int getGliphData(const String &uniChar, int* index, int* charWidth)
{
Serial.println("uniChar data= " + uniChar);
if (uni_name)
{
for (int i = 0; i < uni_name_len; ++i)
{
Serial.println("uni_name[" + String(i) + "]= " + uni_name[i]);
if (uniChar == uni_name[i])
{
*index = i;
*charWidth = char_width[i];
return i;
}
}
}
return -1;
}
或者:
// zar.h
/*v*/extern const unsigned char XB_Zar_118[];
/*w*/extern const unsigned char XB_Zar_119[];
/*x*/extern const unsigned char XB_Zar_120[];
/*y*/extern const unsigned char XB_Zar_121[];
/*z*/extern const unsigned char XB_Zar_122[];
extern const unsigned int XB_Zar_width[];
extern const unsigned char* XB_Zar_addr[];
extern const String XB_Zar_name[];
//zar.cpp
/*v*/ const unsigned char XB_Zar_118[] PROGMEM ={255,255,254,255,63,255};
/*w*/ const unsigned char XB_Zar_119[] PROGMEM ={255,127,255,254,255,5};
/*x*/ const unsigned char XB_Zar_120[] PROGMEM ={215,215,23,254,255,127};
/*y*/ const unsigned char XB_Zar_121[] PROGMEM ={255,127,25,254,255,9};
/*z*/ const unsigned char XB_Zar_122[] PROGMEM ={255,243,239,254,215,19};
const unsigned int XB_Zar_width[] = {2, 2, 2, 2, 2, 0}; // TODO: fix the 6th element!
const unsigned char* XB_Zar_addr[] = {XB_Zar_118, XB_Zar_119, XB_Zar_120, XB_Zar_121, XB_Zar_122, NULL}; // TODO: fix the 6th element!
const String XB_Zar_name[] = {"۰", "۱", "۲", "۳", "۴", "۵", ""}; // TODO: remove the 6th element?
//font.h
#pragma once
#include "zar.h"
extern const unsigned char **char_addr;
extern const unsigned int *char_width;
extern const String *uni_name;
extern void setFont(byte fontNumber);
extern int getGliphData(const String &uniChar, int *index, int *width);
//font.cpp
#include "font.h"
const unsigned char **char_addr = NULL;
const unsigned int *char_width = NULL;
const String *uni_name = NULL;
//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
void setFont(byte fontNumber)
{
switch (fontNumber)
{
case 0:
char_addr = XB_Zar_addr;
char_width = XB_Zar_width;
uni_name = XB_Zar_name;
break;
default:
char_addr = XB_Zar_addr;
char_width = XB_Zar_width;
break;
}
}
//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
int getGliphData(const String &uniChar, int* index, int* charWidth)
{
Serial.println("uniChar data= " + uniChar);
if (uni_name)
{
for (int i = 0; uni_name[i].Length() > 0; ++i)
{
Serial.println("uni_name[" + String(i) + "]= " + uni_name[i]);
if (uniChar == uni_name[i])
{
*index = i;
*charWidth = char_width[i];
return i;
}
}
}
return -1;
}
我已经在 ESP32 微控制器上完成了@RemyLebeau 对 运行 的出色回答。
// zar.h
/*v*/extern const unsigned char XB_Zar_118[];
/*w*/extern const unsigned char XB_Zar_119[];
/*x*/extern const unsigned char XB_Zar_120[];
/*y*/extern const unsigned char XB_Zar_121[];
/*z*/extern const unsigned char XB_Zar_122[];
extern const unsigned int XB_Zar_width[];
extern const unsigned char* XB_Zar_addr[];
extern const String XB_Zar_name[];
extern const int XB_Zar_name_len;
zar.cpp 文件:
//zar.cpp
/*v*/ const unsigned char XB_Zar_118[] PROGMEM ={255,255,254,255,63,255};
/*w*/ const unsigned char XB_Zar_119[] PROGMEM ={255,127,255,254,255,5};
/*x*/ const unsigned char XB_Zar_120[] PROGMEM ={215,215,23,254,255,127};
/*y*/ const unsigned char XB_Zar_121[] PROGMEM ={255,127,25,254,255,9};
/*z*/ const unsigned char XB_Zar_122[] PROGMEM ={255,243,239,254,215,19};
const unsigned int XB_Zar_width[] = {2, 2, 2, 2, 2, 0}; // TODO: fix the 6th element!
const unsigned char* XB_Zar_addr[] = {XB_Zar_118, XB_Zar_119, XB_Zar_120, XB_Zar_121, XB_Zar_122, NULL}; // TODO: fix the 6th element!
const String XB_Zar_name[] = {"۰", "۱", "۲", "۳", "۴", "۵"}; // TODO: remove the 6th element?
const int XB_Zar_name_len = sizeof(XB_Zar_name)/sizeof(XB_Zar_name[0]);
font.h 文件:
//font.h
#pragma once
#include "zar.h"
extern const unsigned char **char_addr;
extern const unsigned int *char_width;
extern const String *uni_name;
extern void setFont(byte fontNumber);
extern int getGliphData(const String &uniChar, int *index, int *width);
font.cpp 文件:
//font.cpp
#include "font.h"
const unsigned char **char_addr = NULL;
const unsigned int *char_width = NULL;
const String *uni_name = NULL;
//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
void setFont(byte fontNumber)
{
switch (fontNumber)
{
case 0:
char_addr = (unsigned char *)pgm_read_ptr(XB_Zar_addr[0]); // use pgm_read_ptr() becuse there is PROGMEM space in flash memory
char_addr = XB_Zar_addr;
char_width = XB_Zar_width;
uni_name = XB_Zar_name;
break;
default:
char_addr = (unsigned char *)pgm_read_ptr(XB_Zar_addr[0]); // use pgm_read_ptr() becuse there is PROGMEM space in flash memory
char_addr = XB_Zar_addr;
char_width = XB_Zar_width;
uni_name = XB_Zar_name;
break;
}
//Now. char_addr points to flash space and no need to use pgm_read_word_near()
// or using pgm_read_byte_near(). Simply use "*(char_addr)" or "*(char_addr+number)"
//Serial.println("char_addr[0]= "+String(*(char_addr))));
//Serial.println("char_addr[1]= "+String(*(char_addr+1)));
//Serial.println("char_addr[3]= "+String(*(char_addr+3)));
}
//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
int getGliphData(const String &uniChar, int* index, int* charWidth)
{
Serial.println("uniChar data= " + uniChar);
if (uni_name)
{
for (int i = 0; uni_name[i].Length() > 0; ++i)
{
Serial.println("uni_name[" + String(i) + "]= " + uni_name[i]);
if (uniChar == uni_name[i])
{
*index = i;
/* *charWidth = char_width[i]; it works if 'i' is
* a const number at compile time.
* constant 'i' only works because the compiler
* sets the value of char_width[i] during
* compilation, char_width[i] is a constant value
* pointing to one specific location in progmem
* that the compiler knows the value of while
* compiling see:https://forum.arduino.cc/t/passing-a-pointer-to-progmem-in-function/637756/5
*/
*charWidth = pgm_read_word_near(char_width+*index);
return i;
}
}
}
return -1;
}
这是一个在MCU中使用字体的程序。我有4个文件。 'zar.h' 和 'zar.cpp' 包含一种字体的数据。 'font.h' 和 'font.cpp' 包含动态设置字体的指针和函数。指针有很多问题。当访问“XB_Zar_name”数组元素时,通过“uni_name[i]”指针,MCU dos reset's。另一个问题是计算“XB_Zar_name”字符串数组中的字符串。修复这些错误后肯定会出现其他错误。请帮助我。
zar.h
/*v*/extern const unsigned char XB_Zar_118[];
/*w*/extern const unsigned char XB_Zar_119[];
/*x*/extern const unsigned char XB_Zar_120[];
/*y*/extern const unsigned char XB_Zar_121[];
/*z*/extern const unsigned char XB_Zar_122[];
extern char XB_Zar_width[];
extern const unsigned char* XB_Zar_addr[];
extern String XB_Zar_name[];
zar.cpp
/*v*/ const unsigned char XB_Zar_118[] PROGMEM ={255,255,254,255,63,255};
/*w*/ const unsigned char XB_Zar_119[] PROGMEM ={255,127,255,254,255,5};
/*x*/ const unsigned char XB_Zar_120[] PROGMEM ={215,215,23,254,255,127};
/*y*/ const unsigned char XB_Zar_121[] PROGMEM ={255,127,25,254,255,9};
/*z*/ const unsigned char XB_Zar_122[] PROGMEM ={255,243,239,254,215,19};
char XB_Zar_width[]= {2,2,2,2,2};
const unsigned char* XB_Zar_addr[] = {XB_Zar_118,XB_Zar_119,XB_Zar_120,XB_Zar_121,XB_Zar_122};
String XB_Zar_name[] = {"۰","۱","۲","۳","۴","۵"};
font.h
#pragma once
#include "zar.h"
extern unsigned char *char_addr;
extern unsigned int *char_width;
extern String **uni_name;
extern void setFont(byte fontNumber);
extern int getGliphData(String *uniChar, int *index, int *width);
font.cpp
#include "font.h"
unsigned char *char_addr = NULL;
unsigned int *char_width = NULL;
String **uni_name = NULL;
//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
void setFont(byte fontNumber)
{
switch (fontNumber)
{
case 0:
char_addr = (unsigned char *)(XB_Zar_addr);
*uni_name = XB_Zar_name;
char_width = (unsigned int *)XB_Zar_width;
break;
default:
char_addr = (unsigned char *)XB_Zar_addr;
break;
}
}
//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
int getGliphData(String *uniChar, int* index, int* charWidth)
{
Serial.println("uniChar data= "+*uniChar);
Serial.println("uni_name[i]= "+*uni_name[0]);// <---this resets the mcu
int countOfUniChars = sizeof(uni_name) / sizeof(String*);
for (int i = 0; i < countOfUniChars ; i++)
{
if (*uniChar == *uni_name[i])
{
*index = i;
*charWidth = char_width[i];
return i;
}
}
return -1;
}
在 getGliphData()
内部,uni_name
只是一个指针,因此您试图用来计算 countOfUniChars
的 sizeof()
技巧根本行不通(那里在 Whosebug 上有很多关于那个问题的问题。
因此,要么在存储数组指针的同时将数组长度存储到另一个全局变量中,要么用哨兵值(在本例中为空字符串)终止每个数组,然后循环遍历数组直到你到达哨兵。
此外,当 String*
指针就足够时,无需使用 String**
指针,因为您仅遍历 1 个 String
数组。如果您遍历指向 String
数组的指针数组,那么 String**
会更有意义。
此外,我看到的另一个问题是 XB_Zar_width[]
和 XB_Zar_addr[]
只有 5 个元素,但 XB_Zar_name[]
有 6 个元素,而 getGliphData()
正在尝试遍历 XB_Zar_name[]
使用其索引访问 XB_Zar_width[]
和 XB_Zar_addr[]
的元素,这显然不适用于第 6 个元素。
话虽这么说,但试试更像这样的东西:
// zar.h
/*v*/extern const unsigned char XB_Zar_118[];
/*w*/extern const unsigned char XB_Zar_119[];
/*x*/extern const unsigned char XB_Zar_120[];
/*y*/extern const unsigned char XB_Zar_121[];
/*z*/extern const unsigned char XB_Zar_122[];
extern const unsigned int XB_Zar_width[];
extern const unsigned char* XB_Zar_addr[];
extern const String XB_Zar_name[];
extern const int XB_Zar_name_len;
//zar.cpp
/*v*/ const unsigned char XB_Zar_118[] PROGMEM ={255,255,254,255,63,255};
/*w*/ const unsigned char XB_Zar_119[] PROGMEM ={255,127,255,254,255,5};
/*x*/ const unsigned char XB_Zar_120[] PROGMEM ={215,215,23,254,255,127};
/*y*/ const unsigned char XB_Zar_121[] PROGMEM ={255,127,25,254,255,9};
/*z*/ const unsigned char XB_Zar_122[] PROGMEM ={255,243,239,254,215,19};
const unsigned int XB_Zar_width[] = {2, 2, 2, 2, 2, 0}; // TODO: fix the 6th element!
const unsigned char* XB_Zar_addr[] = {XB_Zar_118, XB_Zar_119, XB_Zar_120, XB_Zar_121, XB_Zar_122, NULL}; // TODO: fix the 6th element!
const String XB_Zar_name[] = {"۰", "۱", "۲", "۳", "۴", "۵"}; // TODO: remove the 6th element?
const int XB_Zar_name_len = sizeof(XB_Zar_name)/sizeof(XB_Zar_name[0]);
//font.h
#pragma once
#include "zar.h"
extern const unsigned char **char_addr;
extern const unsigned int *char_width;
extern const String *uni_name;
extern int uni_name_len;
extern void setFont(byte fontNumber);
extern int getGliphData(const String &uniChar, int *index, int *width);
//font.cpp
#include "font.h"
const unsigned char **char_addr = NULL;
const unsigned int *char_width = NULL;
const String *uni_name = NULL;
int uni_name_len = 0;
//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
void setFont(byte fontNumber)
{
switch (fontNumber)
{
case 0:
char_addr = XB_Zar_addr;
char_width = XB_Zar_width;
uni_name = XB_Zar_name;
uni_name_len = XB_Zar_name_len;
break;
default:
char_addr = XB_Zar_addr;
char_width = XB_Zar_width;
break;
}
}
//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
int getGliphData(const String &uniChar, int* index, int* charWidth)
{
Serial.println("uniChar data= " + uniChar);
if (uni_name)
{
for (int i = 0; i < uni_name_len; ++i)
{
Serial.println("uni_name[" + String(i) + "]= " + uni_name[i]);
if (uniChar == uni_name[i])
{
*index = i;
*charWidth = char_width[i];
return i;
}
}
}
return -1;
}
或者:
// zar.h
/*v*/extern const unsigned char XB_Zar_118[];
/*w*/extern const unsigned char XB_Zar_119[];
/*x*/extern const unsigned char XB_Zar_120[];
/*y*/extern const unsigned char XB_Zar_121[];
/*z*/extern const unsigned char XB_Zar_122[];
extern const unsigned int XB_Zar_width[];
extern const unsigned char* XB_Zar_addr[];
extern const String XB_Zar_name[];
//zar.cpp
/*v*/ const unsigned char XB_Zar_118[] PROGMEM ={255,255,254,255,63,255};
/*w*/ const unsigned char XB_Zar_119[] PROGMEM ={255,127,255,254,255,5};
/*x*/ const unsigned char XB_Zar_120[] PROGMEM ={215,215,23,254,255,127};
/*y*/ const unsigned char XB_Zar_121[] PROGMEM ={255,127,25,254,255,9};
/*z*/ const unsigned char XB_Zar_122[] PROGMEM ={255,243,239,254,215,19};
const unsigned int XB_Zar_width[] = {2, 2, 2, 2, 2, 0}; // TODO: fix the 6th element!
const unsigned char* XB_Zar_addr[] = {XB_Zar_118, XB_Zar_119, XB_Zar_120, XB_Zar_121, XB_Zar_122, NULL}; // TODO: fix the 6th element!
const String XB_Zar_name[] = {"۰", "۱", "۲", "۳", "۴", "۵", ""}; // TODO: remove the 6th element?
//font.h
#pragma once
#include "zar.h"
extern const unsigned char **char_addr;
extern const unsigned int *char_width;
extern const String *uni_name;
extern void setFont(byte fontNumber);
extern int getGliphData(const String &uniChar, int *index, int *width);
//font.cpp
#include "font.h"
const unsigned char **char_addr = NULL;
const unsigned int *char_width = NULL;
const String *uni_name = NULL;
//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
void setFont(byte fontNumber)
{
switch (fontNumber)
{
case 0:
char_addr = XB_Zar_addr;
char_width = XB_Zar_width;
uni_name = XB_Zar_name;
break;
default:
char_addr = XB_Zar_addr;
char_width = XB_Zar_width;
break;
}
}
//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
int getGliphData(const String &uniChar, int* index, int* charWidth)
{
Serial.println("uniChar data= " + uniChar);
if (uni_name)
{
for (int i = 0; uni_name[i].Length() > 0; ++i)
{
Serial.println("uni_name[" + String(i) + "]= " + uni_name[i]);
if (uniChar == uni_name[i])
{
*index = i;
*charWidth = char_width[i];
return i;
}
}
}
return -1;
}
我已经在 ESP32 微控制器上完成了@RemyLebeau 对 运行 的出色回答。
// zar.h
/*v*/extern const unsigned char XB_Zar_118[];
/*w*/extern const unsigned char XB_Zar_119[];
/*x*/extern const unsigned char XB_Zar_120[];
/*y*/extern const unsigned char XB_Zar_121[];
/*z*/extern const unsigned char XB_Zar_122[];
extern const unsigned int XB_Zar_width[];
extern const unsigned char* XB_Zar_addr[];
extern const String XB_Zar_name[];
extern const int XB_Zar_name_len;
zar.cpp 文件:
//zar.cpp
/*v*/ const unsigned char XB_Zar_118[] PROGMEM ={255,255,254,255,63,255};
/*w*/ const unsigned char XB_Zar_119[] PROGMEM ={255,127,255,254,255,5};
/*x*/ const unsigned char XB_Zar_120[] PROGMEM ={215,215,23,254,255,127};
/*y*/ const unsigned char XB_Zar_121[] PROGMEM ={255,127,25,254,255,9};
/*z*/ const unsigned char XB_Zar_122[] PROGMEM ={255,243,239,254,215,19};
const unsigned int XB_Zar_width[] = {2, 2, 2, 2, 2, 0}; // TODO: fix the 6th element!
const unsigned char* XB_Zar_addr[] = {XB_Zar_118, XB_Zar_119, XB_Zar_120, XB_Zar_121, XB_Zar_122, NULL}; // TODO: fix the 6th element!
const String XB_Zar_name[] = {"۰", "۱", "۲", "۳", "۴", "۵"}; // TODO: remove the 6th element?
const int XB_Zar_name_len = sizeof(XB_Zar_name)/sizeof(XB_Zar_name[0]);
font.h 文件:
//font.h
#pragma once
#include "zar.h"
extern const unsigned char **char_addr;
extern const unsigned int *char_width;
extern const String *uni_name;
extern void setFont(byte fontNumber);
extern int getGliphData(const String &uniChar, int *index, int *width);
font.cpp 文件:
//font.cpp
#include "font.h"
const unsigned char **char_addr = NULL;
const unsigned int *char_width = NULL;
const String *uni_name = NULL;
//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
void setFont(byte fontNumber)
{
switch (fontNumber)
{
case 0:
char_addr = (unsigned char *)pgm_read_ptr(XB_Zar_addr[0]); // use pgm_read_ptr() becuse there is PROGMEM space in flash memory
char_addr = XB_Zar_addr;
char_width = XB_Zar_width;
uni_name = XB_Zar_name;
break;
default:
char_addr = (unsigned char *)pgm_read_ptr(XB_Zar_addr[0]); // use pgm_read_ptr() becuse there is PROGMEM space in flash memory
char_addr = XB_Zar_addr;
char_width = XB_Zar_width;
uni_name = XB_Zar_name;
break;
}
//Now. char_addr points to flash space and no need to use pgm_read_word_near()
// or using pgm_read_byte_near(). Simply use "*(char_addr)" or "*(char_addr+number)"
//Serial.println("char_addr[0]= "+String(*(char_addr))));
//Serial.println("char_addr[1]= "+String(*(char_addr+1)));
//Serial.println("char_addr[3]= "+String(*(char_addr+3)));
}
//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
int getGliphData(const String &uniChar, int* index, int* charWidth)
{
Serial.println("uniChar data= " + uniChar);
if (uni_name)
{
for (int i = 0; uni_name[i].Length() > 0; ++i)
{
Serial.println("uni_name[" + String(i) + "]= " + uni_name[i]);
if (uniChar == uni_name[i])
{
*index = i;
/* *charWidth = char_width[i]; it works if 'i' is
* a const number at compile time.
* constant 'i' only works because the compiler
* sets the value of char_width[i] during
* compilation, char_width[i] is a constant value
* pointing to one specific location in progmem
* that the compiler knows the value of while
* compiling see:https://forum.arduino.cc/t/passing-a-pointer-to-progmem-in-function/637756/5
*/
*charWidth = pgm_read_word_near(char_width+*index);
return i;
}
}
}
return -1;
}