Пытаюсь использовать макрос на C для раскрашивания текста, но получаю: ожидаемая ошибка ‘)’

#c #compiler-errors

#c #ошибки компилятора

Вопрос:

Я пытаюсь написать средство для раскрашивания строки терминала на основе макроса на C для моих будущих проектов. Пока все, что у меня есть, это:

 #define ANSI_RED     "x1b[31m"
#define ANSI_GREEN   "x1b[32m"
#define ANSI_YELLOW  "x1b[33m"
#define ANSI_BLUE    "x1b[34m"
#define ANSI_MAGENTA "x1b[35m"
#define ANSI_CYAN    "x1b[36m"
#define ANSI_RESET   "x1b[0m"

#define ANSI_COLOR(color, string) color string ANSI_RESET

#define FOREGROUND 38
#define BACKGROUND 48

#define RGB_COLOR(plane, r, g, b, string) "33[" plane ";" r ";" g ";" b "m" string ANSI_RESET
  

ANSI_COLOR Макрос работает просто отлично, но когда я пытаюсь использовать RGB_COLOR такой:

 printf( RGB_COLOR(FOREGROUND, 248, 42, 148, "Starting the server:n") );
  

Я получаю сообщение об ошибке:

 /c-http-server/main.c:17:23: error: expected ')'
    printf( RGB_COLOR(FOREGROUND, 248, 42, 148, "Starting the server:n") );
                      ^
/c-http-server/libs/c-chalk/chalk.h:11:20: note: expanded from macro 'FOREGROUND'
#define FOREGROUND 38
                   ^
/c-http-server/main.c:17:11: note: to match this '('
    printf( RGB_COLOR(FOREGROUND, 248, 42, 148, "Starting the server:n") );
  

Я искал эту проблему на SO, и большинство решений были связаны с поиском дополнительного ‘)’, но я не могу найти его в своем коде.

Я был бы рад, если бы кто-нибудь мог помочь мне найти проблему, возможно, я просто слеп и пропустил что-то очевидное.

Комментарии:

1. Один из способов отладки этого — запустить только предварительный компилятор и проверить выходные данные.

2. Вам также нужно указать цвета в виде строк: #define FOREGROUND "38" . Другой способ — использовать оператор stringification в макросе.

3. Лучшим способом было бы вообще не использовать макросы, а функции.

Ответ №1:

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

В качестве быстрого исправления вы могли бы попробовать

 #define FOREGROUND "38"
#define BACKGROUND "48"
  

и использую его как

 printf( RGB_COLOR(FOREGROUND, "248", "42", "148", "Starting the server:n") );
  

С другой стороны, должна быть возможность (и более чистая) упорядочить параметры (непроверенные):

 #define xstr(a) str(a)
#define str(a) #a
#define RGB_COLOR(plane, r, g, b, string) "33[" str(plane) ";" str(r) ";" str(g) ";" str(b) "m" string ANSI_RESET
  

Обратите внимание на обход с помощью xstr и str , потому что строкование предотвращает расширение макроса, как правильно прокомментировал @John Bollinger.

Комментарии:

1. Да и нет для строкового преобразования, потому что оператор строкового преобразования подавляет макрорасширение аргумента, к которому он применяется. Существуют обходные пути, но конкретное альтернативное определение, которое вы представляете для RGB_COLOR , не будет работать так, как хочет OP.