Если у вас есть доступ к C API Tcl, используйте операции dict (вместе с другими соответствующими).
Tcl_Obj *dict = Tcl_NewDictObj();
Tcl_IncrRefCount(dict);
Tcl_DictObjPut(NULL, dict, Tcl_NewStringObj(key1, -1), Tcl_NewStringObj(value1, -1));
// etc, to build the dictionary; you need more care if you have duplicated keys
// Now, get the string value; note that the dict object OWNS the string memory
const char *stringValue = Tcl_GetString(dict);
// and once you don't need stringValue or dict any more
Tcl_DecrRefCount(dict);
В противном случае, если вы можете сформировать список Tcl с четным числом элементов, то это будет интерпретироваться как словарь (строковые представления намеренно совпадают). Предполагая, что вы не хотите использовать операции Tcl_Obj
, есть также низкоуровневые динамические c строки (более старый API, который довольно часто используется внутри, но который сейчас не особенно рекомендуется) :
Tcl_DString buffer;
Tcl_DStringInit(&buffer);
Tcl_DStringAppendElement(&buffer, key1);
Tcl_DStringAppendElement(&buffer, value1);
// ...
const char *stringValue = Tcl_DStringValue(&buffer);
// and once you're done with everything
Tcl_DStringFree(&buffer);
Прежде чем вы спросите, как и в случае Tcl_Obj
, Tcl_DString
владеет памятью, связанной с stringValue
. Вам нужно будет взять копию, если вы хотите, чтобы она сохранялась после освобождения буфера. (Обратите внимание, что API Tcl_Obj
потенциально более эффективен, за исключением того, что на самом деле все, что вы в конечном итоге делаете, это строит из него строку.)
Если вы хотите сами управлять распределением памяти есть абсолютный базовый уровень API 1019 *. В частности, Tcl_ScanElement
позволит вашему коду решить, как эффективно отформатировать определенную строку элемента (он возвращает оценку требуемого пространства и, с помощью параметра OUT, инструкции о том, как выполнить форматирование), а Tcl_ConvertElement
выполните форматирование в буфер, который вы подготовили. Их использование немного затруднительно, поэтому я просто сошлюсь на , как сам Tcl использует их (это часть реализации объектов списка Tcl).
Если вы не tcl C API вообще не доступен, знайте, что вы хотите создать последовательность слов, разделенных пробелами. Для простых слов (например, только с буквенно-цифровыми или большинством пунктуации c) вы можете просто вставить слова непосредственно. Для чего-либо более сложного (т. Е. Если оно содержит метасимвол Tcl, такой как [
, $
, \
или любой другой пробел), вам необходимо либо заключить их в {
фигурные скобки }
, либо поставить обратную косую черту перед оскорбительные персонажи. Установка скобок работает в большинстве случаев (основной, в которой она не работает, это несбалансированные скобки; есть несколько других). Использование обратной косой черты в работах во всех случаях, но безобразно; это тот тип вещей, который довольно легко генерировать для кода, но на самом деле ужасный для чтения и отладки, особенно с вложенными списками.
Это правила для списки. Словари по формату эквивалентны спискам с четным количеством элементов. Существует два требования к каноничности словарей: пробелы, разделяющие слова, должны быть единичными пробелами (это форма канонического списка), а ключи словаря (первый, третий, пятый ... элементы) должны быть уникальными. Неканонические словари работают и точно определены (предпочтение отдается ключу last ), но могут иногда удивлять, если вы не продумываете внимание. Собственный кодовый словарь Tcl всегда канонизирует словарь, когда записывает в него (потому что внутренняя модель - это таблица ha sh; ваш код C не не требует его построения).