извлечь дублирующийся вложенный символ * из нескольких символов*

#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"};
  

для вас.