join () или implode () в C - PullRequest
       9

join () или implode () в C

4 голосов
/ 13 января 2011

Одна вещь, которая мне нравится в Python и PHP, это возможность легко создавать строки из массива:

Python: ', '.join(['a', 'b', 'c'])
PHP: implode(', ', array('a', 'b', 'c'));

Однако мне было интересно, есть ли у кого-нибудь интуитивно понятный и понятный способ реализовать это в C.Спасибо!

Ответы [ 3 ]

9 голосов
/ 13 января 2011

Конечно, есть способы - просто ничего встроенного. Многие служебные библиотеки C имеют функции для этого - например, glib's g_strjoinv . Вы также можете свернуть свои собственные, например:

static char *util_cat(char *dest, char *end, const char *str)
{
    while (dest < end && *str)
        *dest++ = *str++;
    return dest;
}

size_t join_str(char *out_string, size_t out_bufsz, const char *delim, char **chararr)
{
    char *ptr = out_string;
    char *strend = out_string + out_bufsz;
    while (ptr < strend && *chararr)
    {
        ptr = util_cat(ptr, strend, *chararr);
        chararr++;
        if (*chararr)
            ptr = util_cat(ptr, strend, delim);
    }
    return ptr - out_string;
}

Основная причина, по которой он не встроен, в том, что стандартная библиотека C очень минимальна; они хотели упростить создание новых реализаций C, чтобы вы не нашли столько полезных функций. Существует также проблема, заключающаяся в том, что C не дает вам много рекомендаций о том, как, например, решить, сколько элементов в массивах (в приведенном выше примере я использовал соглашение об ограничении NULL-массива-элемента).

5 голосов
/ 13 января 2011

Например, в GLib есть такая функция: g_strjoin и g_strjoinv .Возможно, любая большая библиотека имеет такие функции.

Самый простой способ - использовать такие библиотеки и быть счастливым.Также не сложно написать это самостоятельно (посмотрите на другие ответы).«Большая» проблема заключается в том, что вы должны быть осторожны при распределении и освобождении этих строк.Это C; -)

Edit: я просто вижу, что вы использовали в обоих примерах массивов.Так что вы знаете: g_strjoinv - это то, что вы просили.

4 голосов
/ 13 января 2011

Я нашел функцию, которая делает это в ANSI C здесь . Я адаптировал его и добавил аргумент-разделитель. Обязательно освободите строку () после ее использования.

char* join_strings(char* strings[], char* seperator, int count) {
    char* str = NULL;             /* Pointer to the joined strings  */
    size_t total_length = 0;      /* Total length of joined strings */
    int i = 0;                    /* Loop counter                   */

    /* Find total length of joined strings */
    for (i = 0; i < count; i++) total_length += strlen(strings[i]);
    total_length++;     /* For joined string terminator */
    total_length += strlen(seperator) * (count - 1); // for seperators

    str = (char*) malloc(total_length);  /* Allocate memory for joined strings */
    str[0] = '\0';                      /* Empty string we can append to      */

    /* Append all the strings */
    for (i = 0; i < count; i++) {
        strcat(str, strings[i]);
        if (i < (count - 1)) strcat(str, seperator);
    }

    return str;
}
...