LINUX.ORG.RU

Красивый способ превращать числа в строки, заданные подобным #define IAC 0x01

 ,


1

3

Не придумывается ничего, кроме массива строк. Массив сформировать sed/awk из #define

#include <stdio.h>

void main ()
{
  char * a[3] = {"DO",
		 "IAC",
		 "F\0z"};
  int i;

  for (i=0; i<3; i++) {
    printf("%s\n", a[i]);
  }
}

А в common lisp как можно?



Последнее исправление: panzerito (всего исправлений: 2)

Ответ на: комментарий от Crocodoom

Мне нужно поступающие числовые данные преобразовывать в строки и выводить в терминал. То есть поступил 0x01, вывожу «IAC».

panzerito
() автор топика
Последнее исправление: panzerito (всего исправлений: 1)
Ответ на: комментарий от panzerito

Если #define можно переделать, то можно как-то так (X Macro):

#include <stdio.h>

#define IDS \
        X(none, 0x00) \
        X(IAC, 0x01) \
        X(IAB, 0x02)

enum {
#define X(id, value) id = value,
IDS
#undef X
};

static const char *map[] = {
#define X(id, value) [value] = #id,
IDS
#undef X
};

void main ()
{
  unsigned int i;

  for (i=0U; i<sizeof(map)/sizeof(map[0]); ++i) {
    printf("%d = %s\n", i, map[i]);
  }
}
$ ./a.out
0 = none
1 = IAC
2 = IAB
xaizek ★★★★★
()

В ЦЛ просто заводить массив строк и выбираешь нужную по номеру.

anonymous
()

А в common lisp как можно?

alist, hashmap, дженерики, сахарок на макросах. Если числа без пропусков, то просто массив строк.

Массив сформировать sed/awk из #define

Зачем?

no-such-file ★★★★★
()
Ответ на: комментарий от anonymous

Покажи на примере такого выражения:

(cdr
 (assoc
  (read)
   '(
    (18446744073709551615 . "The maximum unsigned 64 bit value")
    (4294967295 . "The maximum unsigned 32 bit value (2^32 - 1)")
    (65535 . "The maximum unsigned 16 bit value (2^16 - 1)")
    (255 . "The maximum unsigned 8 bit value (2^8 - 1")
    (9223372036854775807 . "The maximum signed 64 bit value")
    (2147483647 . "The maximum signed 32 bit valu")
    (32767 . "The maximum signed 16 bit value")
    (127 . "The maximum signed 8 bit value")
    (-128 . "Minimum signed 8 bit value")
    (-32768 . "Minimum signed 16 bit value")
    (-2147483648 . "Minimum signed 32 bit value")
    (-9223372036854775808 . "Minimum signed 64 bit value"))))

anonymous
()
Ответ на: комментарий от anonymous

Тут уже хэш-таблицы лучше. Последний раз сравнивал на СБЦЛ - это лучше ощущается только после достаточно большого количества элементов - после 30-50.

ados ★★★★★
()
Ответ на: комментарий от panzerito

Можешь подсказать в виде идеи?

Вообще я не очень понял, зачем тебе это надо. Судя по всем заморочкам, ты хочешь получать строковое представление идентификатора константы/переменной. Так вот в лиспе это есть из коробки, т.к. для любого символа можно получить строку через symbol-name.

> (setf IAC 1)
1

> (symbol-name 'IAC)
"IAC"

Если же тебе надо по числу получить строку, или символ, то тут уже без списка(массива, хэша и т.п.) символов никак не обойтись. Вот тут пригодится макрос, который засетапит значения переданных символов и список самих символов.

В итоге должно получиться что-то вроде такого

(defenum *codes* (IAC 1 FOO 2 BAR 3))
;;; Делает
;;; (setf IAC 1 FOO 2 BAR 3)
;;; (defvar *codes* (list 'IAC 'FOO 'BAR))
;;; по желанию можно deftype

(find-enum *codes* 1)
;;; Проходим по *codes*, ищем (= (symbol-value i) 1) возвращаем i и/или (symbol-name i)

Можно ещё сахарка накинуть, прикрутить switch по *codes* и т.п.

no-such-file ★★★★★
()
Последнее исправление: no-such-file (всего исправлений: 1)

В CL есть аналог switch в C --- case. Если список констант известен на этапе компиляции или расходы на (compile nil '(lambda (id) (case id ...))) пренебрежимо малы, то можно через него.

Jini ★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.