Выполнение замены строки

Как выглядит следующая замена строки в C? Является ли этот подход более распространенным, чем выделение памяти внутри функции и возврат нового указателя на строку, или же более распространен «принеси-свой-собственный-буфер»?

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


// return size of string, -1 if error such as buffer too small
// no memory is allocated here, buffer needs to be passed in
// Example: str_replace("Replace me", "me", "ME", buffer, 64);
// Returns: 10, buffer is now "Replace ME".
ssize_t 
str_replace (
        const char* input_str, 
        const char* from, 
        const char* to, 
        char* output_buffer, 
        size_t max_size
) {
    size_t input_len = strlen(input_str);
    size_t from_size = strlen(from);
    size_t to_size = strlen(to);

    // get the output string length;
    size_t output_len = input_len;
    char* str_iterator = (char*) input_str;
    while ((str_iterator=strstr(str_iterator, from))) {
        output_len += (to_size - from_size);
        str_iterator += from_size;
    }
    if (output_len > max_size) {
        fprintf(stderr, "Buffer too small for output string.n");
        return -1;
    }

    // reset str_iterator, make sure output_buffer is clear
    str_iterator = (char*) input_str;
    output_buffer[0] = ' ';

    // copy to output buffer
    // 1. Find the first match of `from` in `input_str` (advancing pointer on input_buffer along way)
    // 2. Copy the input_str up until the first match to output_buffer
    // 3. Copy `from` into output_buffer (advance string)
    // 4. Advance input_buffer pointer by size of `from`
    // 5. Repeat 2-5 until no more matches
    // 6. Copy remainder of input_str to output_buffer
    for (char* match; (match=strstr(str_iterator, from)); str_iterator+= (match-str_iterator) + from_size) {
        strncpy(output_buffer, str_iterator, match-str_iterator);
        output_buffer += (match-str_iterator);
        strncpy(output_buffer, to, to_size);
        output_buffer += to_size;
    }
    // copy remainder
    if (strlen(str_iterator))
        strcpy(output_buffer, str_iterator);

    return output_len;
}
int main(void)
{
    char buffer[50];
    ssize_t out_size = str_replace("Replace me", "me", "ME", buffer, 50);
    if (out_size == -1)
        printf("Nope!n");
    else
        printf("Response size: %zu.nResponse string: %sn", out_size, buffer);
}

$ gcc logmain.c -o log; ./бревно
Размер ответа: 10.
Строка ответа: Заменить ME

И еще одна альтернатива:

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

// same as above but now with malloc
char* str_replace2(const char* input, const char* from, const char* to)
{
    size_t input_len = strlen(input);
    size_t from_size = strlen(from);
    size_t to_size = strlen(to);
    char* str_iterator = (char*) input;

    // get the output string length;
    size_t output_len = input_len;
    while ((str_iterator=strstr(str_iterator, from))) {
        output_len += (to_size - from_size);
        str_iterator += from_size;
    }
    char *str_out = malloc(output_len);
    char * const str_out_start = str_out; // const for emphasis it doesn't change
    if (!str_out) {
        fprintf(stderr, "Cannot malloc str of size %zu", output_len);
        return NULL;
    }

    // write to output str
    str_iterator = (char*) input;
    for (char* match; (match=strstr(str_iterator, from)); str_iterator+= (match-str_iterator) + from_size) {
        strncpy(str_out, str_iterator, match-str_iterator);
        str_out += (match-str_iterator);
        strncpy(str_out, to, to_size);
        str_out += to_size;
    }
    // copy remainder
    if (strlen(str_iterator))
        strcpy(str_out, str_iterator);

    return str_out_start;
}

Кроме того, где обычно помещаются комментарии в C? Над функцией? В функции?

1 ответ
1

Несколько вещей, которые нужно учесть.

  1. Почему вы пишете собственную реализацию чего-то, что уже существует, с долгой историей надежного использования с четко определенным поведением (развлечение / задание — конечно, обычно — трата усилий, которая может привести к проблемам)?

  2. Что, если input, from, или же to равны нулю или недействительны (не

Добавить комментарий

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