Макрос C: превратить число в строку

У меня есть таблица, определяющая внешний вид символов на дисплее с разрешением 5x7 точек. Что-то типа:

extern UINT8 symbols[][5] = {
    {0x0,0x0,0x0,0x0,0x0},
    {0x0,0x0,0x5F,0x0,0x0},
    {0x0,0x7,0x0,0x7,0x0},
    {0x14,0x7F,0x14,0x7F,0x14}, // etc.

Начальная часть таблицы соответствует таблице ASCII, за которой следует набор специальных символов, например. стрелку или галочку. Чтобы сослаться на них, у меня есть список макросов:

#define SYMBOL_LEFT_ARROW 120 // 120 is the entry in the table
#define SYMBOL_RIGHT_ARROW (SYMBOL_LEFT_ARROW+1)    
#define SYMBOL_UP_ARROW (SYMBOL_RIGHT_ARROW+1)

Теперь мне нужно сказать что-то вроде (не будет компилироваться):

const char * const message = "Next" + SYMBOL_RIGHT_ARROW;

Вопрос: как преобразовать SYMBOL_RIGHT_ARROW в "\x79" или всю строку в "Next\x79" ВО ВРЕМЯ КОМПИЛЯЦИИ, чтобы я мог иметь строку в разделе R/O?

C-компилятор Freescale HC08.


person THX-1138    schedule 20.10.2009    source источник
comment
Я бы постарался избежать создания строк во время выполнения: 1) дополнительных циклов; 2) Я хотел бы сохранить константные строки в ПЗУ (это встроенная система).   -  person THX-1138    schedule 20.10.2009


Ответы (3)


Вы можете объединить строки в источнике C:

printf("%s\n", "forty" "two"); /* prints "fortytwo" */
/* NOTE:             ^^^ no punctuation */

Чтобы сделать это с вашими символами, нужно много работать, но, возможно, вы сможете жить с этим.

#define SYMBOL_LEFT_ARROW 120
#define SYMBOL_LEFT_ARROW_STR "\x79"
#define SYMBOL_RIGHT_ARROW (SYMBOL_LEFT_ARROW + 1)
#define SYMBOL_RIGHT_ARROW_STR "\x83"
const char * const message = "Next" SYMBOL_RIGHT_ARROW_STR;

ОБНОВЛЕНИЕ

Если вы можете сделать так, чтобы значение символа совпадало с его позицией в таблице символов (120 соответствует "\x78"), попробуйте эти макросы

#include <stdio.h>

#define ADD_ZERO_X(y) 0x ## y
#define SYMBOL_NUM(x) ADD_ZERO_X(x)

#define STRINGIZE(z) #z
#define ADD_SLASH_X(y) STRINGIZE(\x ## y)
#define SYMBOL_STR(x) ADD_SLASH_X(x)

#define SYMBOL_LEFT_ARROW 78 /* must write in hexadecimal without any prefix */
#define SYMBOL_RIGHT_ARROW 79
#define SYMBOL_UP_ARROW 7a

int main(void) {
  printf("%d\n", SYMBOL_NUM(SYMBOL_LEFT_ARROW));
  printf("%s\n", SYMBOL_STR(SYMBOL_LEFT_ARROW));
  printf("%d\n", SYMBOL_NUM(SYMBOL_RIGHT_ARROW));
  printf("%s\n", SYMBOL_STR(SYMBOL_RIGHT_ARROW));
  printf("%d\n", SYMBOL_NUM(SYMBOL_UP_ARROW));
  printf("%s\n", SYMBOL_STR(SYMBOL_UP_ARROW));
  return 0;
}

Изменить (SO не любит мой браузер)

После раскрытия макроса SYMBOL_NUM(32) преобразуется в целочисленный литерал (0x78); а SYMBOL_STR(78) преобразуется в строковый литерал ("\x78").

Вы можете использовать литералы так, как если бы вы их напечатали.

const char *test = "Next" SYMBOL_STR(78) " one";
/* same as
   const char *test = "Next\x78 one";
*/
person pmg    schedule 20.10.2009

Я придумал эту небольшую программу:

#include <stdio.h>

#define TEST_CHR '\x77'
#define VAL(x) #x
#define STRINGIFY(x) VAL(x)
int main()
{
   int x = TEST_CHR;
   char *yyy = "%d " STRINGIFY(TEST_CHR) "\n";

   printf(yyy,x);

   return 0;

}

косвенность в макросе необходима, чтобы ваш символ был расширен до того, как «#» превратит его в строку. обратите внимание, что значение '\ x77' превращается в допустимое целое число, когда вы используете его таким образом...

person steve alexander    schedule 20.10.2009
comment
Как сделать '\x77' из #define MY_SYMBOL 0x77? - person THX-1138; 21.10.2009
comment
#MY_SYMBOL создаст \x77, но не '\x77'. - person Joseph Garvin; 21.10.2009
comment
я думаю, что «\ x77» займет место 0x77 в выражениях int? (таким образом, назначение x в main)... - person steve alexander; 22.10.2009
comment
также я думаю: char my_literal[] = {Next STRINGIFY(TEST_CHR)}; // должен быть romable... - person steve alexander; 22.10.2009

Это лучшее, что я мог придумать, не идеально, но его можно поместить в ПЗУ:

const char message[] = {'N','e','x','t',SYMBOL_RIGHT_ARROW,EOS};
person THX-1138    schedule 20.10.2009