сложение строк
От: DemAS http://demas.me
Дата: 07.03.08 09:22
Оценка:
А есть ли в C более короткая запись сложения двух строк?

#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>

int main() {
   char *s1 = "abc";
   char *s2 = "def";
   int i;

   for (i=1; i<=10; i++) {
     char *sum = (char*)malloc(255);
     sum[0] = '\0';
     strcat(sum, s1);
     strcat(sum, s2);
     printf("%s\n", sum);
     free(sum);
   }
}
Posted via RSDN NNTP Server 2.1 beta
Re: сложение строк
От: ДимДимыч Украина http://klug.org.ua
Дата: 07.03.08 09:25
Оценка:
Здравствуйте, DemAS, Вы писали:

DAS>А есть ли в C более короткая запись сложения двух строк?


В C вообще строк нет, не говоря уж об их сложении.
Обязательно бахнем! И не раз. Весь мир в труху! Но потом. (ДМБ)
Re[2]: сложение строк
От: DemAS http://demas.me
Дата: 07.03.08 09:29
Оценка:
Не придирайся, это не я придумал:
#include <string.h>
Posted via RSDN NNTP Server 2.1 beta
Re: сложение строк
От: LaptevVV Россия  
Дата: 07.03.08 09:32
Оценка:
Здравствуйте, DemAS, Вы писали:

DAS>
DAS>#include <string.h>
DAS>#include <stdlib.h>
DAS>#include <stdio.h>
DAS>#include <unistd.h>

DAS>int main() {
DAS>   char *s1 = "abc";
DAS>   char *s2 = "def";
DAS>   int i;

DAS>   for (i=1; i<=10; i++) {
DAS>     char *sum = (char*)malloc(255);
DAS>     sum[0] = '\0';
DAS>     strcat(sum, s1);
DAS>     strcat(sum, s2);
DAS>     printf("%s\n", sum);
DAS>     free(sum);
DAS>   }
DAS>}
DAS>

А зачем 10 раз сцепляешь? Просто для тренировки?
Хочешь быть счастливым — будь им!
Без булдырабыз!!!
Re[2]: сложение строк
От: DemAS http://demas.me
Дата: 07.03.08 09:35
Оценка:
> А зачем 10 раз сцепляешь? Просто для тренировки?

Просто демо пример. В реальной программе на каждом шаге цикла будут
складываться разные строки.

Интресует, есть ли готовая обертка над последовательностью действий:

1) обрезать то, что было заполнено на предыдущем шаге
2) скопировать первую строку
3) скопировать вторую строку
Posted via RSDN NNTP Server 2.1 beta
Re: сложение строк
От: Bell Россия  
Дата: 07.03.08 09:37
Оценка: 3 (1) +1
Здравствуйте, DemAS, Вы писали:

DAS>А есть ли в C более короткая запись сложения двух строк?


DAS>
DAS>#include <string.h>
DAS>#include <stdlib.h>
DAS>#include <stdio.h>
DAS>#include <unistd.h>

DAS>int main() {
DAS>   char *s1 = "abc";
DAS>   char *s2 = "def";
DAS>   int i;

DAS>   for (i=1; i<=10; i++) {
DAS>     char *sum = (char*)malloc(255);
DAS>     sum[0] = '\0';
DAS>     strcat(sum, s1);
DAS>     strcat(sum, s2);
DAS>     printf("%s\n", sum);
DAS>     free(sum);
DAS>   }
DAS>}

DAS>



char *s1 = "abc";
char *s2 = "def";
char *s3 = (char*)malloc(strlen(s1) + strlen(s2) + 1);
sprintf(s3, "%s%s", s1, s2);
free(s3);
Любите книгу — источник знаний (с) М.Горький
Re: сложение строк
От: Sharp Eye Россия  
Дата: 07.03.08 09:47
Оценка: +1
Здравствуйте, DemAS, Вы писали:

[skip]

М.б. что-то вроде этого?


char * concat(const char * s1, const char * s2)
{
    size_t l1 = strlen(s1);
    size_t l2 = strlen(s2);
    size_t len = l1 + l2 + 1;

    char * dst = (char *)malloc(len);

    memcpy(dst, s1, l1);
    memcpy(dst + l1, s2, l2);
    dst[len - 1] = 0;

    return dst;
}

...

char * str = concat("abc", "def");


printf(str);

free(str);
Re[2]: сложение строк
От: DemAS http://demas.me
Дата: 07.03.08 09:54
Оценка:
Ну, что-то типа этого, только искал стандартное, а не самописное.
Вариант Bell вполне устроил.

Кстати, в предложенном тобой коде мне не нравится то, что память
вызывается в функции, а освобождается в нее ее. То есть, тот, кто
использует функцию может даже не знать, что он что-то обязан освободить.
Posted via RSDN NNTP Server 2.1 beta
Re: сложение строк
От: igna Россия  
Дата: 07.03.08 09:57
Оценка:
Здравствуйте, DemAS, Вы писали:

DAS>     sum[0] = '\0';
DAS>     strcat(sum, s1);
DAS>     strcat(sum, s2);


Можно заменить на:

     strcat(strcpy(sum, s1), s2);
Re[3]: сложение строк
От: Angler Россия  
Дата: 07.03.08 10:10
Оценка:
Здравствуйте, DemAS, Вы писали:

DAS>Кстати, в предложенном тобой коде мне не нравится то, что память

DAS>вызывается в функции, а освобождается в нее ее. То есть, тот, кто
DAS>использует функцию может даже не знать, что он что-то обязан освободить.

коментируй, см. к примеру strdup
Re[3]: сложение строк
От: Sharp Eye Россия  
Дата: 07.03.08 10:26
Оценка:
Здравствуйте, DemAS, Вы писали:

DAS>Ну, что-то типа этого, только искал стандартное, а не самописное.

DAS>Вариант Bell вполне устроил.

sprintf более универсальная функция, чем этого требует твоя задача.

DAS>Кстати, в предложенном тобой коде мне не нравится то, что память

DAS>вызывается в функции, а освобождается в нее ее. То есть, тот, кто
DAS>использует функцию может даже не знать, что он что-то обязан освободить.

Ну да, есть немного. Пардон, исправляюсь:



char * concat(char * dst, const char * s1, const char * s2)
{
    size_t l1 = strlen(s1);
    size_t l2 = strlen(s2);
    size_t len = l1 + l2 + 1;

    memcpy(dst, s1, l1);
    memcpy(dst + l1, s2, l2);
    dst[len - 1] = 0;

    return dst;
}

...

    char * s1 = "abc";
    char * s2 = "def";

    // сами вычисляем размер, сами выделяем память
    char * str = (char *)malloc(strlen(s1) + strlen(s2) + 1);
    str = concat(str, s1, s2);

    printf(str);

    free(str);

    char buffer[255];

    // можно использовать стек
    str = concat(buffer, s1, s2);
    printf(str);
Re[3]: сложение строк
От: Bell Россия  
Дата: 07.03.08 10:28
Оценка:
Здравствуйте, DemAS, Вы писали:

DAS>Ну, что-то типа этого, только искал стандартное, а не самописное.

Судя по всему, стандартной функции нет
DAS>Вариант Bell вполне устроил.
Проверь на производительность, если это критично. ИМХО вариант с memcpy должен быть быстрее.

DAS>Кстати, в предложенном тобой коде мне не нравится то, что память

DAS>вызывается в функции, а освобождается в нее ее. То есть, тот, кто
DAS>использует функцию может даже не знать, что он что-то обязан освободить.

Ну это вопрос докуменитрования — strdup тоже выделяет память, которую должен освободить пользователь.
Так что можно просто переименовать concat в concat_and_dont_forget2free_result
Любите книгу — источник знаний (с) М.Горький
Re[2]: сложение строк
От: igna Россия  
Дата: 07.03.08 10:37
Оценка:
Здравствуйте, Bell, Вы писали:

B>sprintf(s3, "%s%s", s1, s2);


Да, но к сожалению, если в этом месте будет ошибка вроде:

sprintf("%s%s", s1, s2, s3);


, то немаловероятно, что компилятор ее не заметит.

Это замечание относится ко всем функциям со строкой форматирования, потому может быть не стоит использовать их там, где можно обойтись функциями из <string.h>.
Re[4]: сложение строк
От: Sharp Eye Россия  
Дата: 07.03.08 10:37
Оценка:
Здравствуйте, Sharp Eye, Вы писали:

[skip]

А потом, мы еще немного упрощаем функцию, и получаем...



char * concat(char * dst, const char * s1, const char * s2)
{
    *dst = 0;

    strcat(dst, s1);
    strcat(dst, s2);

    return dst;
}



... твой вариант, только на 3 строчки короче:



for (i=1; i<=10; i++) {
     char *sum = (char*)malloc(255);
     concat(sum, s1, s2);
     printf("%s\n", sum);
     free(sum);
   }
Re[2]: сложение строк
От: Plague Россия  
Дата: 07.03.08 10:39
Оценка:
Здравствуйте, igna, Вы писали:

I>Можно заменить на:


I>
I>     strcat(strcpy(sum, s1), s2);
I>


Тогда уж сразу так :
    char *sum = strcat(strcpy(malloc(strlen(s1)+strlen(s2)+1), s1), s2);
    printf(sum);
    free(sum);
... << RSDN@Home 1.2.0 alpha rev. 787>>
Re[3]: сложение строк
От: Plague Россия  
Дата: 07.03.08 10:42
Оценка:
Здравствуйте, igna, Вы писали:

I>Это замечание относится ко всем функциям со строкой форматирования, потому может быть не стоит использовать их там, где можно обойтись функциями из <string.h>.


У меня решение было такое же как у Bell, но перегрузил Janus, а ответ уже дали... )

в добавок sprintf СЕРЬЕЗНО тормознее остальных решений...
... << RSDN@Home 1.2.0 alpha rev. 787>>
Re[4]: сложение строк
От: Bell Россия  
Дата: 07.03.08 10:45
Оценка:
Здравствуйте, Plague, Вы писали:

P>Здравствуйте, igna, Вы писали:


I>>Это замечание относится ко всем функциям со строкой форматирования, потому может быть не стоит использовать их там, где можно обойтись функциями из <string.h>.


P>У меня решение было такое же как у Bell, но перегрузил Janus, а ответ уже дали... )

Ну уж извиняйте

P>в добавок sprintf СЕРЬЕЗНО тормознее остальных решений...

Я в этом тоже признался
Любите книгу — источник знаний (с) М.Горький
Re[5]: сложение строк
От: igna Россия  
Дата: 07.03.08 10:46
Оценка: +1
Здравствуйте, Sharp Eye, Вы писали:

SE>char * concat(char * dst, const char * s1, const char * s2)
SE>{
SE>    *dst = 0;

SE>    strcat(dst, s1);
SE>    strcat(dst, s2);

SE>    return dst;
SE>}


Если заменить первый strcat на strcpy, то и обнуление *dst будет не нужно.

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

И последнее (спорное): Я бы вернул указатель на конец строки, поскольку указатель на начало у вызывающего уже есть.
Re[6]: сложение строк
От: Sharp Eye Россия  
Дата: 07.03.08 10:59
Оценка:
Здравствуйте, igna, Вы писали:

I>Здравствуйте, Sharp Eye, Вы писали:


I>
SE>>char * concat(char * dst, const char * s1, const char * s2)
SE>>{
SE>>    *dst = 0;

SE>>    strcat(dst, s1);
SE>>    strcat(dst, s2);

SE>>    return dst;
SE>>}
I>


I>Если заменить первый strcat на strcpy, то и обнуление *dst будет не нужно.


I>И если писать свою функцию, то можно и об эффективности позаботиться, поскольку неизвестно заранее, не будет ли она когда-либо использована в ситуации, где будет важна максимальная скорость. Я имею ввиду то, что у тебя второй strcat пробегает строку с самого начала в поисках нуля.


I>И последнее (спорное): Я бы вернул указатель на конец строки, поскольку указатель на начало у вызывающего уже есть.

Все подобные функции возвращают dst.
Re[7]: сложение строк
От: igna Россия  
Дата: 07.03.08 11:14
Оценка:
Здравствуйте, Sharp Eye, Вы писали:

SE>Все подобные функции возвращают dst.


Да. Что в общем то бесполезно, зато привычно.
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.