#c #char #concat
#c #символ #конкатенация
Вопрос:
У меня есть a, struct
конструктор которого принимает a char*
(в отличие от a std::string
). Я хочу создать несколько экземпляров этого класса с аналогичными параметрами:
struct X {
char* x;
};
// usage
X xx = {"x.com/x"};
X xy = {"x.com/y"};
X xz = {"x.com/z"};
Параметры немного сложны, а общая вложенная «строка» длиннее, чем просто «x.com /», поэтому его извлечение помогло бы сделать его более читаемым, но я не уверен, как:
const static char* domain = "x.com/";
X xx = {domain "x"};
X xy = {domain "y"};
X xz = {domain "z"};
Я пробовал объявлять domain
как std::string
, char*
, char[]
. Я также пробовал опускать и не опускать
. Я хотел бы избежать создания локальных переменных или использования strcopy
, поскольку я полагаю, что это минимизировало бы выигрыш в читаемости кода за счет усложнения чего-то, что в идеале должно состоять из ~ 3 коротких строк. Кроме того, я заставил его работать, объявив domain
as std::string
и вызвав .c_str()
; например X xx = {(domain "x").c_str()};
, но это тоже ухудшает читаемость imo.
Я полагаю, что вероятный ответ заключается в том, что я должен смириться с повторением вложенных строк или использовать что-то, что добавляет многословия. Но, возможно, мое невежество в C и отсутствие точной терминологии означают, что я пропустил что-то очевидное при попытке поиска решений.
Правка, касающаяся изменения X
:
Я не могу изменить свою структуру X
(это своего рода зависимость / утилита), используемую во многих местах нашей кодовой базы, и она не всегда создается с помощью «x.com /» при использовании в другом месте.
Комментарии:
1. FWIW
X xx = {(domain "x").c_str()};
оставляет вас с зависшим указателем, так что это определенно не то, что вы хотите (он также не должен компилироваться, потому что это нарушает корректность const). Простой способ обойти это —X
сохранить ссылку на общую часть, а затем создать переменную-член, которая имеет не общую часть.2. О, я не знал о проблеме с указателем. Что касается предложения, структура X используется во многих других местах более крупной командой. Я не могу его изменить, и он не всегда создается с помощью «x.com /» при использовании в другом месте.
Ответ №1:
Во-первых, присвоение строкового литерала a char*
устарело в C 03 и было удалено из C 11. x
должно быть const char*
стандартной жалобой.
Поскольку вы не можете изменять X
, вы можете использовать небольшую хитрость, используя тот факт, что строковые литералы, которые не разделены ничем, кроме пробела, объединяются во время процесса компиляции. Это означает, что если у вас есть
"hello " "world"
компилятор объединит его в
"hello world"
Зная это, вы можете использовать препроцессор для определения символа типа
#define DOMAIN "x.com/"
и затем вы можете использовать его для инициализации ваших объектов, таких как
X xx = {DOMAIN "x"};
X xy = {DOMAIN "y"};
X xz = {DOMAIN "z"};
который разрешается в
X xx = {"x.com/x"};
X xy = {"x.com/y"};
X xz = {"x.com/z"};
для вас.