Перейти к содержанию
    

C, вставить символ внутри строки

Допустим, есть строка

  static const uint8_t *TestText = "Test string";

Хочу вставить в середину специальный символ, допустим \x18. Откуда он возьмется, не важно (сам нарисую). Это можно сделать так:

  static const uint8_t *TestText = "Test\x18string";

Но мне не нравятся эти ничего не говорящие числа. Как можно подменить с помощью #define символ, чтобы принимался внутри строки?

И попутно, как вставить символ, например, 'A', внутрь строки?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

#define MY_SYMBOL_NAME "\x18"
static const uint8_t *TestText = "Test" MY_SYMBOL_NAME "string";

Строковые литералы идущие подряд через withespace склеиваются компилятором в один литерал. Так можно засунуть дефайн внутрь строки, но в дефайне может быть только строковый литерал.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Чем конкатенация строк на этапе компиляции не устраивает? :)

Или еще есть оператор препроцессора # - "превращения" в строку.

 

упс. извините neiver уже успел ответить :)

Изменено пользователем winipuh

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

#define MY_SYMBOL_NAME "\x18"
static const uint8_t *TestText = "Test" MY_SYMBOL_NAME "string";

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

 

Или еще есть оператор препроцессора # - "превращения" в строку.

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

error: #10: "#" not expected here

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

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

 

 

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

error: #10: "#" not expected here

##

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

 

Вот если использовать вложенные макросы, типа

#define CONCAT(a,b ) a##b

 

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

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

##

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

 

Вот если использовать вложенные макросы, типа

#define CONCAT(a,b ) a##b

 

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

Это немного из другой области и в данном случае не нужно.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Тут вот еще какая засада. Хотел спецсимволы описать в перечислении, вместо #define.

typedef enum {
  S_BKL = 0x10,
  S_GND,
...
} SYM_t;

Но это будут уже не строковые константы, а числа. Если добавить # - Кейл ругается (уже писал). Если взять в кавычки - так и уйдут на вывод "S_GND".

Так что, возможно, MrYuran прав. Но проще, похоже, описать дефайнами каждый символ в виде строки. :)

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Опять не могу сообщение отправить, начиная с полуночи, или раньше!

Вопрос - как бы элемент перечисления превратить в односимвольную строку, чтобы использовать, как мне нужно. Типа

#define SSYM(X) "\x#X"

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Вопрос - как бы элемент перечисления превратить в односимвольную строку, чтобы использовать, как мне нужно. Типа
Вероятно никак. Значения enum получает на этапе компиляции, а склейку строк делает препроцессор.

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Проблема тут в том, что Вы хотите выполнить конкатенацию строки с символом ("abcd" + '2'), а в си этого не предусмотрено.

Хотя если погуглить - видно что Вы не единственный такой в мире. :) Вот пример (правда похоже, что не рабочий).

Задачу, наверное, Вы сможете решить только придумаете как средствами препроцессора разбить строку на массив символов (попытки также можно найти в инете), плюс использование составных литералов, которые появились в С99:

#include <stdio.h>
int main(void) {
    enum spec_symb_t {
        PLUS  = 0x2b,
        MINUS = 0x2d
    };
    puts("+-");
    puts((const char[]) {PLUS, MINUS, '\0'}); 
    return 0;
}

 

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

 

p.s. может быть здесь сможете что-то найти...

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Проблема тут в том, что Вы хотите выполнить конкатенацию строки с символом ("abcd" + '2'), а в си этого не предусмотрено.

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

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

Уже использую, в своем изделии. Сам шрифт создал, сам и текст вывожу, на свой же ЖКИ. Например, S_DELTA"X=".

До этого символы, не входящие в ANSI набор, рисовал отдельно, в отдельном массиве. Теперь решил объединить со стандартными, все равно первые 32 места "пропадают".

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Так уже выяснили,что можно склеивать строки. А строка из одного символа - такая же полноправная строка. Замечательно, что при склейке строк промежуточные нули уничтожаются. Этого механизма мне достаточно.
Вы меня не поняли. :)

Чуть ранее Вы говорили о использовании enum вместо define (о чем Вы говорили чуть ранее). Мой опус был посвящен именно этому. И в этой связи речь шла о проблеме склейки строковой константы с символьной константой, а не о склейке двух строк...

Если бы знал, что уже Вы уже вариант с enum отбросили и остановились на использовании #define :)

 

Изменено пользователем winipuh

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Вы меня не поняли. :)

Чуть ранее Вы говорили о использовании enum вместо define (о чем Вы говорили чуть ранее). Мой опус был посвящен именно этому. И в этой связи речь шла о проблеме склейки строковой константы с символьной константой, а не о склейке двух строк...

Я не против - превратить перечисление в строку. Но пока что, увы... :laughing: Поэтому остановился на работающем решении.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Если сильных возражений не будет, то хотелось бы в этой теме пролить свет и на такой момент:

Задача передать в параметрах компиляции строку. Не получается(

Число передать можно. Например,

  SW_VER_BUILD    = 1005
  COMPILE_OPTS      = $(CPU_OPTS) -fpack-struct -Wpadded -g -O$(OPT) -DSW_VER_BUILD=$(SW_VER_BUILD)

А вот строку - никак (и я скорее всего понимаю почему не получается).

Но может есть варианты?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Можно и строку в кавычках в дефайн передать, только кавычки нужно экранировать. не знаю как в makefile с кавычками, но просто в командной строке Windows они экранируются символом \

gcc hello.cpp -o hello.exe -DMY_DEFINE=\"hello\"

Соответственно макрос MY_DEFINE будет иметь значение "hello" - строковый литерал.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Присоединяйтесь к обсуждению

Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.

Гость
К сожалению, ваш контент содержит запрещённые слова. Пожалуйста, отредактируйте контент, чтобы удалить выделенные ниже слова.
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

×
×
  • Создать...