Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: C, вставить символ внутри строки
Форум разработчиков электроники ELECTRONIX.ru > Сайт и форум > В помощь начинающему > Программирование
ViKo
Допустим, есть строка
Код
  static const uint8_t *TestText = "Test string";

Хочу вставить в середину специальный символ, допустим \x18. Откуда он возьмется, не важно (сам нарисую). Это можно сделать так:
Код
  static const uint8_t *TestText = "Test\x18string";

Но мне не нравятся эти ничего не говорящие числа. Как можно подменить с помощью #define символ, чтобы принимался внутри строки?
И попутно, как вставить символ, например, 'A', внутрь строки?
neiver
Код
#define MY_SYMBOL_NAME "\x18"
static const uint8_t *TestText = "Test" MY_SYMBOL_NAME "string";

Строковые литералы идущие подряд через withespace склеиваются компилятором в один литерал. Так можно засунуть дефайн внутрь строки, но в дефайне может быть только строковый литерал.
winipuh
Чем конкатенация строк на этапе компиляции не устраивает? sm.gif
Или еще есть оператор препроцессора # - "превращения" в строку.

упс. извините neiver уже успел ответить sm.gif
ViKo
Цитата(neiver @ Apr 26 2013, 15:50) *
Код
#define MY_SYMBOL_NAME "\x18"
static const uint8_t *TestText = "Test" MY_SYMBOL_NAME "string";

Получилось, спасибо! И без пробелов тоже склеилось.

Цитата(winipuh @ Apr 26 2013, 15:52) *
Или еще есть оператор препроцессора # - "превращения" в строку.

И как применить...? Если внутри строки написать "Test"#MY_SYMBOL"string", Keil ругается
error: #10: "#" not expected here
MrYuran
Цитата(ViKo @ Apr 26 2013, 17:24) *
Получилось, спасибо! И без пробелов тоже склеилось.


И как применить...? Если внутри строки написать "Test"#MY_SYMBOL"string", Keil ругается
error: #10: "#" not expected here

##
Правда, результат в данном случае будет не такой, как надо.

Вот если использовать вложенные макросы, типа
#define CONCAT(a,b ) a##b

тогда можно попробовать CONCAT("Test", MY_STRING)
ar__systems
Цитата(MrYuran @ Apr 26 2013, 08:30) *
##
Правда, результат в данном случае будет не такой, как надо.

Вот если использовать вложенные макросы, типа
#define CONCAT(a,b ) a##b

тогда можно попробовать CONCAT("Test", MY_STRING)

Это немного из другой области и в данном случае не нужно.
ViKo
Тут вот еще какая засада. Хотел спецсимволы описать в перечислении, вместо #define.
Код
typedef enum {
  S_BKL = 0x10,
  S_GND,
...
} SYM_t;

Но это будут уже не строковые константы, а числа. Если добавить # - Кейл ругается (уже писал). Если взять в кавычки - так и уйдут на вывод "S_GND".
Так что, возможно, MrYuran прав. Но проще, похоже, описать дефайнами каждый символ в виде строки. sm.gif
ViKo
Опять не могу сообщение отправить, начиная с полуночи, или раньше!
Вопрос - как бы элемент перечисления превратить в односимвольную строку, чтобы использовать, как мне нужно. Типа
#define SSYM(X) "\x#X"
Сергей Борщ
QUOTE (ViKo @ Apr 27 2013, 11:31) *
Вопрос - как бы элемент перечисления превратить в односимвольную строку, чтобы использовать, как мне нужно. Типа
Вероятно никак. Значения enum получает на этапе компиляции, а склейку строк делает препроцессор.
winipuh
Проблема тут в том, что Вы хотите выполнить конкатенацию строки с символом ("abcd" + '2'), а в си этого не предусмотрено.
Хотя если погуглить - видно что Вы не единственный такой в мире. sm.gif Вот пример (правда похоже, что не рабочий).
Задачу, наверное, Вы сможете решить только придумаете как средствами препроцессора разбить строку на массив символов (попытки также можно найти в инете), плюс использование составных литералов, которые появились в С99:
Код
#include <stdio.h>
int main(void) {
    enum spec_symb_t {
        PLUS  = 0x2b,
        MINUS = 0x2d
    };
    puts("+-");
    puts((const char[]) {PLUS, MINUS, '\0'});
    return 0;
}


Попутно у меня к Вам возникает встречный вопрос - ради чего такая акробатика в коде? sm.gif Вы где и как это предполагаете использовать?

p.s. может быть здесь сможете что-то найти...
ViKo
Цитата(winipuh @ Apr 27 2013, 23:37) *
Проблема тут в том, что Вы хотите выполнить конкатенацию строки с символом ("abcd" + '2'), а в си этого не предусмотрено.

Так уже выяснили,что можно склеивать строки. А строка из одного символа - такая же полноправная строка. Замечательно, что при склейке строк промежуточные нули уничтожаются. Этого механизма мне достаточно.
Цитата
Попутно у меня к Вам возникает встречный вопрос - ради чего такая акробатика в коде? sm.gif Вы где и как это предполагаете использовать?

Уже использую, в своем изделии. Сам шрифт создал, сам и текст вывожу, на свой же ЖКИ. Например, S_DELTA"X=".
До этого символы, не входящие в ANSI набор, рисовал отдельно, в отдельном массиве. Теперь решил объединить со стандартными, все равно первые 32 места "пропадают".
winipuh
Цитата(ViKo @ Apr 29 2013, 08:27) *
Так уже выяснили,что можно склеивать строки. А строка из одного символа - такая же полноправная строка. Замечательно, что при склейке строк промежуточные нули уничтожаются. Этого механизма мне достаточно.
Вы меня не поняли. sm.gif
Чуть ранее Вы говорили о использовании enum вместо define (о чем Вы говорили чуть ранее). Мой опус был посвящен именно этому. И в этой связи речь шла о проблеме склейки строковой константы с символьной константой, а не о склейке двух строк...
Если бы знал, что уже Вы уже вариант с enum отбросили и остановились на использовании #define sm.gif
ViKo
Цитата(winipuh @ Apr 29 2013, 14:26) *
Вы меня не поняли. sm.gif
Чуть ранее Вы говорили о использовании enum вместо define (о чем Вы говорили чуть ранее). Мой опус был посвящен именно этому. И в этой связи речь шла о проблеме склейки строковой константы с символьной константой, а не о склейке двух строк...

Я не против - превратить перечисление в строку. Но пока что, увы... laughing.gif Поэтому остановился на работающем решении.
adnega
Если сильных возражений не будет, то хотелось бы в этой теме пролить свет и на такой момент:
Задача передать в параметрах компиляции строку. Не получается(
Число передать можно. Например,
Код
  SW_VER_BUILD    = 1005
  COMPILE_OPTS      = $(CPU_OPTS) -fpack-struct -Wpadded -g -O$(OPT) -DSW_VER_BUILD=$(SW_VER_BUILD)

А вот строку - никак (и я скорее всего понимаю почему не получается).
Но может есть варианты?
neiver
Можно и строку в кавычках в дефайн передать, только кавычки нужно экранировать. не знаю как в makefile с кавычками, но просто в командной строке Windows они экранируются символом \
Код
gcc hello.cpp -o hello.exe -DMY_DEFINE=\"hello\"

Соответственно макрос MY_DEFINE будет иметь значение "hello" - строковый литерал.
adnega
Цитата(neiver @ Apr 29 2013, 17:49) *
Можно и строку в кавычках в дефайн передать, только кавычки нужно экранировать. не знаю как в makefile с кавычками, но просто в командной строке Windows они экранируются символом \

Спасибо! Так работает и в makefile.
AHTOXA
Цитата(adnega @ Apr 29 2013, 18:04) *
Но может есть варианты?

Код
gcc -DCODENAME=HELLO main.cpp

#define xstr(s) str(s)
#define str(s) #s
#define FW_CODENAME            ""xstr(CODENAME)

std::cout << FW_CODENAME << "\r\n";
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.