LINUX.ORG.RU

Шок от С. Как склеивать строки?

 


13

7

Осваиваю си. Всё шло хорошо пока внезапно не понадобилось склеить строки (константные и переменные). Покурил stackoverflow. Предлагают 2 варианта:

Первый - создать char buf[молись_чтобы_хватило] и делать str(n)cat/sprintf в этот buf.

Второй - использовать asprintf, который расширение, нестандарт и вообще.

Вопрос: как вы склеиваете строки? Может есть какая-нибудь общепринятая либа?

Простите за нубский вопрос

★★★★★

Последнее исправление: makoven (всего исправлений: 1)
Ответ на: комментарий от anonymous

что на C++ решается хуже, чем на си?

Некоторые дебилоиды и под микроконтроллеры на С++ пишут, в итоге хеллоуворлд в 8КБ не влезает...ж

Eddy_Em ☆☆☆☆☆
()
Ответ на: комментарий от Eddy_Em

В таких случаях обычно отключают исключения и или вообще не используют шаблоны или следят за разбуханием кода.

В этих условиях С++ все равно оказывается удобнее Си(RAII, перегрузка функций, вывод типов и пр.).

anonymous
()
Ответ на: комментарий от Eddy_Em

Некоторые дебилоиды и под микроконтроллеры на С++ пишут, в итоге хеллоуворлд в 8КБ не влезает...ж

Ты что-то с чем-то путаешь. Во-первых хеллоуворлд и на С в 8Кб уже не влезет. Это если говорить про gcc + elf, например. А на С++ под микроконтроллеры можно практически полноценный HTTP сервер в 8Кб вместить. Со всеми фишками С++, кроме всяких там std::, ес-но.

anonymous
()
Ответ на: комментарий от Eddy_Em

Да что ты говоришь! Просто не нужно stdlib использовать!

Я тебе о том же и говорю. Не используй libstdc++ - и получишь компактный выхлоп.

anonymous
()
Ответ на: комментарий от anonymous

Только черт ногу сломит в этом С++.

Зачем усложнять?

Проще С может быть только ассемблер, но на ассемблере писанины слишком много.

Eddy_Em ☆☆☆☆☆
()
Ответ на: комментарий от Eddy_Em

Зачем усложнять?

Данный топик показывает обратное. Простое a + b в С++ превращается в массу вариантов на С разной степени кривости.

anonymous
()
Ответ на: комментарий от anonymous

Простое a + b в С++

Это извращение — обзывать конкатенацию двух больших кусков памяти знаком "+". Ничего общего со сложением эта операция не имеет.

В С все логично делается, а в извращенном С++ с его перегруженными операторами черт ногу сломит!

Eddy_Em ☆☆☆☆☆
()
Ответ на: комментарий от Eddy_Em

Во-первых хеллоуворлд и на С в 8Кб уже не влезет

Да что ты говоришь! Просто не нужно stdlib использовать!

до какого размера ты можешь уменьшить хеловорлд на си?

unt1tled ★★★★
()
Ответ на: комментарий от unt1tled

Зависит от микроконтроллера: инициализация периферии у всех разная.

На какой-нибудь элементарный STM8 вот такой хеллоуворлд занял 680 байт:

void uart_write(char *str){
    while(*str){
        UART2_DR = *str++;
        while(!(UART2_SR & UART_SR_TC));
    }
}

int main(){
    // Configure pins
    // PD5 - UART2_TX -- pseudo open-drain output; don't forget an pullup resistor!
    PORT(UART_PORT, DDR) |= UART_TX_PIN;
    PORT(UART_PORT, ODR) &= ~UART_TX_PIN; // turn off N push-down
    // Configure UART
    // 9 bit, no parity, 1 stop (UART_CR3 = 0 - reset value)
    // 57600 on 16MHz: BRR1=0x11, BRR2=0x06
    UART2_BRR1 = 0x11; UART2_BRR2 = 0x06;
    UART2_CR1  = UART_CR1_M; // M = 1 -- 9bits
    UART2_CR2  = UART_CR2_TEN | UART_CR2_REN | UART_CR2_RIEN; // Allow RX, generate ints on rx

    do{
        uart_write("Hello world!");
    }while(1);
}
но тут sdcc используется, gcc не умеет 8-битные, к сожалению. А gcc мог бы и сильней ужать.

В принципе, можно было бы под STM32F030 попробовать подобное сделать, но лень мне сейчас клепать тест.

Eddy_Em ☆☆☆☆☆
()
Ответ на: комментарий от Eddy_Em

Это извращение — обзывать конкатенацию двух больших кусков памяти знаком «+». Ничего общего со сложением эта операция не имеет.

окей:

a.append( b );

а в извращенном С++ с его перегруженными операторами черт ногу сломит!

в реальности все не так страшно

anonymous
()
Ответ на: комментарий от anonymous

А на С++ под микроконтроллеры можно практически полноценный HTTP сервер в 8Кб вместить

Пример в студию!

CYB3R ★★★★★
()
Ответ на: комментарий от anonymous

a.append( b );

Вот так нормально. Это можно и в сях сделать.

в реальности все не так страшно

А у меня до сих пор глаз дергается от упоминания С++. Нанесенная травма глубока...

Eddy_Em ☆☆☆☆☆
()
Ответ на: комментарий от Eddy_Em

Однако все-же много строк писать приходится. Намедни писал функцию, возвращающую строку со временем:

char *get_time() {
  static const int strlen = 20;
  time_t now = time(NULL);
  if ( -1 == now) return NULL;
  struct tm *cal_now = localtime(&now);
  if (NULL == cal_now) return NULL;
  char *stime = malloc(strlen);
  if (NULL == stime) return NULL;
  if(0 == strftime(stime, strlen, "%H:%M:%S", cal_now)){
    free(stime);
    return NULL;
  }
  return stime;
}
makoven ★★★★★
() автор топика
Последнее исправление: makoven (всего исправлений: 1)
Ответ на: комментарий от CYB3R

Пример в студию!

код проприетарный, показать не могу, 8Кб - это ес-но сам блоб, еще дополнительно используется память стека под данные, парсится все в том же буфере без дополнительных выделений памяти, никаких std::string - только char*, только хардкор, так и быстрее и опять же память дополнительная не нужна

anonymous
()
Ответ на: комментарий от Eddy_Em

Это можно и в сях сделать.

Если точно известно, что строка выделена на куче, а если передать указатель на строку в стеке - будет жопа. В С++ за такое отвечает аллокатор и std::string::append все-равно кем и как выделена строка. Хоть malloc, хоть alloca, хоть свой пул.

anonymous
()
Ответ на: комментарий от anonymous

std::string::append

а точнее std::basic_string::append

anonymous
()
Ответ на: комментарий от anonymous

Если точно известно, что строка выделена на куче, а если передать указатель на строку в стеке - будет жопа

Ну уж разбираться в своем коде ты обязан.

Eddy_Em ☆☆☆☆☆
()
Ответ на: комментарий от Eddy_Em

Здравый смысл подсказывал, что врят-ли время поломается. Но в манах неумолимо «если фейл - верну NULL/-1»

makoven ★★★★★
() автор топика
Ответ на: комментарий от Eddy_Em

Ну уж разбираться в своем коде ты обязан.

Люди постоянно делают ошибки, если отобрать у них такую возможность - код станет лучше.

anonymous
()
Ответ на: комментарий от Eddy_Em

Это можно и в сях сделать

Но за 40 лет не сделано и не принято в стандарт.

invy ★★★★★
()
Ответ на: комментарий от CYB3R

А что там удивительного? Простой http сервер это около 1к строчек чистого C + функции ввода-вывода.

http://www.st.com/st-web-ui/static/active/en/resource/technical/document/appl... смотреть foot print information

Если поискать на st.com STSW-STM32060 то будут и исходники.

Для сравнения - простая реализация STL для embedded - 17k строк

stlport 48k строк. В отличии от сишного кода темплейты могу раздуются с каждым использованным типом в бинарнике.

anonymous
()
Ответ на: комментарий от Eddy_Em

страуструп кресты придумал как раз для проектов овер 9000 лок, которые пишут несколько человек

anonymous
()
Ответ на: комментарий от makoven
char *
get_time()
{
#define SAFECALL(STMT, ERVAL, FREE) do { if ((STMT) == ERVAL) { FREE; return NULL; } } while (0)

        char *stime = NULL;
        static const int strlen = 20;
        time_t now;
        struct tm *cal_now;

        SAFECALL( now = time(NULL), -1,                            (void)stime);
        SAFECALL( cal_now = localtime(&now), NULL,                 (void)stime);
        SAFECALL( stime = malloc(strlen), NULL,                    (void)stime);
        SAFECALL( strftime(stime, strlen, "%H:%M:%S", cal_now), 0, free(stime));
        return stime;

#undef SAFECALL
}
anonymous
()
Ответ на: комментарий от anonymous

Вспомнилась игрушка http://www.kongregate.com/games/coolio_niato/light-bot

Где приходилось составлять максимально общий, хоть и неоптимальный алгоритм, подходящий под разные маршруты. Иногда робот беспричинно прыгал на месте, делал ненужные развороты, но зато проходил большие отрезки пути с помошью одного и того же алгоритма)

makoven ★★★★★
() автор топика
Ответ на: комментарий от Eddy_Em

Это извращение — обзывать конкатенацию двух больших кусков памяти знаком «+»

Так сделано в очень многих языках. Это удобно.

В С все логично делается

То-то ты не справился :)

anonymous
()
Ответ на: комментарий от Eddy_Em

Это извращение — обзывать конкатенацию двух больших кусков памяти знаком «+». Ничего общего со сложением эта операция не имеет.

Это не извращение, ты оперируешь объектом, который имеет свойства и методы. «+» - условно для удобства назвали метод объекта для контактации. Вот в математике, существует умножение чисел, согласно твоей логике, векторное умножение - это «извращение аналитической геометрии». В ООП, в случае строк, мы асбрагируемся (инкапсулируемся) от памяти, все это спрятано внутри объекта и нам необязательно знать, как оно работает внутри, логично?

nikolnik ★★★
()
Ответ на: комментарий от makoven

ясно. ты меня с другим анонимусом попутал

anonymous
()
Ответ на: комментарий от nikolnik

символ + в качестве конкатенации это кто то поленился да и набор символов небогат

но даже ^ могло бы лучше ибо нет ассоциаций вбитых школьным образованием к символу +

тоже и с присвоением.

qulinxao ★★☆
()
Ответ на: комментарий от qulinxao

символ + в качестве конкатенации это кто то поленился да и набор символов небогат

Если честно, то вообще абсолютно все равно, можешь хоть HERWENDASOSI назови. Мне это никогда не мешалоло.

но даже ^ могло бы лучше ибо нет ассоциаций вбитых школьным образованием к символу +

Когда я біл в десятом классе, я одному парню писал класс на С++ реализющий векторі в геометрическом смісле для какой-то лабі. Оператор ^ біл векторным умножением, т.к. был наиболее похож на символ перпендикулярности и позволял векторное умножение записать как a ^ b * c просто перегрузив операторі ^ и *.

nikolnik ★★★
()
Ответ на: комментарий от nikolnik

озволял векторное умножение записать

точне смешанное векторное умножение

nikolnik ★★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.