Как заставить макрос c работать с галочкой?

Я работаю над проектом C++, в котором используется макрос C строковая. На данный момент все довольно просто, но теперь мне нужно добавить строку, содержащую одну кавычку '. У меня возникли проблемы с тем, чтобы заставить это работать должным образом. Вот минимальная демонстрация проблемы:

#include <stdio.h>

#define myprint(s) \
   printf("passed string: %s", #s)

int main ()
{
    myprint(print this);  // <-- works fine, no quotes.
    printf("\n");
    //myprint(I'm happy); // <-- ' trips things up
    myprint("I'm happy"); // <-- This works, but double 
                          //     quotes are in the output.
    return 0;
}

В богболте: https://godbolt.org/z/oWGxovnPT

Я хочу myprint сделать вывод следующим образом:

I'm happy

Может ли кто-нибудь помочь мне сделать это?


Я привел минимальный пример выше. Если это полезно, именное изменение, которое я пытаюсь внести, — это добавить поддержку 418 I'm a teapot к серверу трафика Apache:

https://github.com/apache/trafficserver/blob/2492c84cddce48cb12acd5c799739103e2f648da/src/proxy/hdrs/HTTP.cc#L832-L833

Зачем тебе это нужно? Какова основная проблема, которую предполагается решить? И обратите внимание, что использование макросов в C++ в целом крайне не рекомендуется, и что хотя C и C++ используют один и тот же препроцессор, это два разных языка, и тегирование обоих также не рекомендуется. Пожалуйста, отмечайте только тот язык, на котором вы на самом деле программируете.

Some programmer dude 19.04.2024 18:07

Цитаты — не единственная ваша проблема. Последовательности длиной > 1 пробела будут свернуты в один пробел, символы новой строки удалены, боковые пробелы обрезаны.

HolyBlackCat 19.04.2024 18:08

Почему myprint обычная функция не принимает const char*?

Ted Lyngmo 19.04.2024 18:08

Это не работает так: препроцессор не обрабатывает произвольный набор байтов; скорее, у него есть свой собственный язык вещей («токены»), который он понимает. И I'm не входит в их число. Язык препроцессора слабо соответствует потребностям «реальных» языков, возникающих в результате предварительной обработки (C, C++ и т. д.).

Kerrek SB 19.04.2024 18:10

@Someprogrammerdude: добавлена ​​конкретная проблема, над которой я работаю.

firebush 19.04.2024 18:13

Почему нельзя просто "-заключить строку в кавычки?

HolyBlackCat 19.04.2024 18:14

Зачем использовать макрос, а не правильную функцию (и необработанные строковые литералы)? Макросов вообще следует избегать.

Jesper Juhl 19.04.2024 18:14

@HolyBlackCat: строковая обработка добавит к строке буквальные кавычки ".

firebush 19.04.2024 18:14

Вы просите, чтобы myprint(print this); работало (без кавычек) и myprint("I'm happy"); работало (без кавычек)?

Drew Dormann 19.04.2024 18:14

«Строковка добавит к строке буквальные " кавычки». Если вы просто заключаете в кавычки каждую строку, вам не нужна строковая обработка.

Drew Dormann 19.04.2024 18:15

' начинает символьную константу, но она не завершается, что приводит к синтаксической ошибке.

Ian Abbott 19.04.2024 18:21

Макросы работают с правильными токенами предварительной обработки, одинарная кавычка без соответствия одинарной кавычке не является допустимым токеном предварительной обработки. Либо вы переименовываете его в I am a teapot, либо вам придется отказаться от стиля этой функции и добавить еще один макрос, либо написать case вручную (я, честно говоря, не понимаю необходимости в макросах здесь, это не значит, что они добавляют больше читаемости по сравнению с обычными case 100: return "Continue"; цепочка...)

Yksisarvinen 19.04.2024 18:21

«Строковка добавит буквальные «кавычки». Да, я говорю, чтобы избавиться от стрингификации и передавать кавычки вручную.

HolyBlackCat 19.04.2024 18:24

@KerrekSB, спасибо. Похоже, что «ответ» для меня заключается в том, что строковая обработка не будет работать для этого проблемного пространства. Я просто заменю каждое из них строками в кавычках. Не стесняйтесь добавлять ответ, объясняющий это.

firebush 19.04.2024 18:26

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

Ian Abbott 19.04.2024 18:29

Если вы хотите сохранить макросы и добиться хотя бы небрежного соответствия RFC 2324, вы можете выбрать какой-нибудь похожий символ, например обратный апостроф.

teapot418 19.04.2024 18:30

На самом деле это выполнимо, пусть и не портативно и, честно говоря, довольно некрасиво. Попробуйте myprint(I\x27m happy).

n. m. could be an AI 19.04.2024 18:36
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
0
17
73
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Ответ принят как подходящий

Вы не можете. Решение состоит в том, чтобы удалить стрингификацию препроцессора.

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

То, что вы хотите, это

case 418: return "I'm a teapot";

Но пока вы там, подставьте все остальные дела.

Спасибо: github.com/apache/trafficserver/pull/11273

firebush 19.04.2024 21:25

То, о чем вы просите, сделать невозможно: препроцессор не обрабатывает произвольные входные символы, как вы могли ожидать. Скорее, у него есть свой собственный язык (например, для C++ см. [cpp]; C имеет аналогичную спецификацию), где единицами обработки являются «токены» (ищите создание грамматики токена предварительной обработки).

«Токены», которые обрабатывает препроцессор, соответствуют языку, который он в конечном итоге обслуживает. То есть токены препроцессора в некоторой степени ориентированы на токены «уровня C++», но отличаются от них, получаемые при создании грамматики токена в [lex.token].

Последовательность символов I'm не является допустимым токеном предварительной обработки.

Другие вопросы по теме