Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > C/C++: Общие вопросы > Создание строки, средствами компилятора


Автор: null56 25.5.2009, 16:51
Хотел поинтересноваться следующей темой, существует ли возможность создать строковую константу во время компиляции состоящую из других строковых констант, поясню чего хочу...
У меня есть имя тега, которое я использую в парсере, но так же это имя хочу использовать в создание xml файла, но получается, что я дублирую код и изменяя одно, приходится изменять другое, что мне не совсем по душе... собственно код
Код

const char TagName[] = "my_tag";
const char OpenTagName[] = "<my_tag>";
const char CloseTagName[] = "</my_tag>";

видно из кода, что константы практически одинаковые и изменив переменную TagName, я должен менять переменные OpenTagName и CloseTagName, что не очень хорошо.
Я хочу попросить об этом компилятор, примерно, чего хочу добиться, выглядит в примере ниже, который, ЕСТЕСТВЕННО НЕ СКОМПИЛИТСЯ
Код

const char TagName[] = "my_tag";
char OpenTagName[strlen(TagName+3)] = strcat(strcat(strcat(OpenTagName, "<"), TagName), ">");
char CloseTagName[strlen(TagName+3)] = strcat(strcat(strcat(CloseTagName, "</"), TagName), ">");

Пример выше, замечу, лишь показывает чего я хочу от компилятора, но не знаю, как граммотно это сделать и возможно ли такое, поэтому обращаюсь за помощью...
Использование строк из библиотеки stl, которые будут в какой - нибудь функции создавать нужные тега, меня не интересуют, вопрос именно по примеру выше...

Заранее благодарен всех откликнувшихся

Автор: mes 25.5.2009, 17:17
не до конца понял требования, но в любом случае, если нужнa манипуляция со строками на этапе компиляции, то надо прибегать к помощи препроцессора.
вот пример , приспосабливайте под свои условия :
Код

#define  DEF_TAGS(tag, value) const char tag ## _Name[]  =      value;         \
                              const char tag ## _Open[]  =  "<" value ">";     \
                              const char tag ## _Close[] = "</" value ">";

    DEF_TAGS(Tag, "test");

#undef DEF_TAGS

int main(){


    std::cout << Tag_Name  << std::endl;
    std::cout << Tag_Open  << std::endl;
    std::cout << Tag_Close << std::endl;

    return 0;

}


Автор: null56 25.5.2009, 19:54
mes, то что надо, спасибо.... с макросами мало работал

Автор: math64 26.5.2009, 08:49
Без макросов:
Код

class Tag {
char* name;
char* openTag;
char* closeTag;
public:
Tag(const char* name);
~Tag();
const char* Name() { return name; }
const char* OpenTag() { return openTag; }
const char* CloseTag() { return closeTag; }
};

Tag::Tag(const char* p_name) {
int len = strlen(name);
name = new char[len+1];
openTag = new char[len+3];
closeTag = new char[len+4];
strcpy (name, p_name);
sprintf(openTag, "<%s>", p_name);
sprintf(closeTag, "</%s>", p_name);
}

Tag::~Tag() {
delete name;
delete openTag;
delete closeTag;
}

Tag mytag("mytag");

Автор: null56 26.5.2009, 10:45
math64, ну это уже исполняемый код, тоже самое, что и со стрингами можно сделать, но без new

Автор: math64 26.5.2009, 12:34
Без исполняемого кода - только макросы. Но без new можно обойтись.
Код

char FillTag(const char* TagName, char* OpenTagName, char* CloseTagName);

const char TagName[] = "my_tag";
char OpenTagName[sizeof(TagName)+2];
char CloseTagName[sizeof(TagName)+3];
// Только C++! В С FillTag нужно вызвать из main()
char dummy = FillTag(TagName, OpenTagName, CloseTagName);

char FillTag(const char* TagName, char* OpenTagName, char* CloseTagName) {
sprintf(OpenTagName, "<%s>", TagName);
sprintf(CloseTagName, "</%s>", TagName);
return 0;
}


Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)