Хабр Курсы для всех
РЕКЛАМА
Практикум, Хекслет, SkyPro, авторские курсы — собрали всех и попросили скидки. Осталось выбрать!
Самое простое решение может быть не самым удачным только в двух случаяхВ теории разницы между теорией и практикой нет — а на практике есть. Вся проблема в т.н. «дырявых абстракциях» — большинство вещей устроено намного сложнее, чем позволяет предположить их внешний интерфейс. Примеров множество — конкатенация строк в цикле без использования StringBuilder-а, побайтовое копирование памяти, работа с сетевыми ФС как с локальными, перемещение файлов между границами разделов, «заторы» в TCP, использование регулярок без кэша, и т.д.
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <stdbool.h>
typedef uint32_t ucs4_t;
#define DEFAULT_CAPACITY 16
#define CAPACITY_MULTIPLIER 125
ucs4_t *strip(const ucs4_t *restrict string, const ucs4_t *restrict chars) {
ucs4_t single_ch = *chars++;
if (!single_ch) { // no filter chars
size_t size;
{
const ucs4_t *string_top = string;
while (*string_top++) { };
size = sizeof(ucs4_t) * (string_top - string);
}
ucs4_t *restrict result;
if (!(result = malloc(size))) {
return NULL;
}
memcpy(result, string, size);
return result;
}
size_t size = DEFAULT_CAPACITY;
ucs4_t *result_base, *result_top, *result;
ucs4_t *_result_base;
ucs4_t ch;
bool single_mode = !*chars;
uint64_t *bitmap = NULL;
if (!single_mode) {
if (!(bitmap = calloc(1, 0x110000 / sizeof(*bitmap)))) {
return NULL;
}
chars--;
while ((ch = *chars++)) {
bitmap[ch / 64] |= 1 << (ch % 64);
}
}
if (!(result_base = result = malloc(size))) {
goto fail;
}
result_top = result_base + size;
while ((ch = *string++)) {
if (single_mode) {
if (ch == single_ch) {
continue;
}
} else {
if (bitmap[ch / 64] & (1 << (ch % 64))) {
continue;
}
}
*result++ = ch;
if (result == result_top) {
size_t offset = size;
size = 1 + size * CAPACITY_MULTIPLIER / 100;
if (!(_result_base = realloc(result_base, size))) {
goto fail;
}
result_base = _result_base;
result_top = result_base + size;
result = result_base + offset;
}
}
*result = 0;
if (!(_result_base = realloc(result_base, sizeof(ucs4_t) * (result - result_base + 1)))) {
goto fail;
}
result_base = _result_base;
return result_base;
fail:
free(bitmap);
free(result_base);
return NULL;
}
// Пример вызова: ucs4_t *result = strip(U"zqHeqllzo, __qwzor_lzd!q_q", U"zq_");
И третье, опытному программисту, скорее всего, эта статья не откроет новые горизонты, но остальным, мы надеемся, сэкономит драгоценные минуты их личной жизни.А потом люди удивляются — как так выходит, что современные компы тупят, как в старые-добрые времена? Ну, зато программист время сэкономил. Ваш подход учит неопытных программистов плохому, и это грустно.
MSLibrary. ПРОСТО: удаляем из строки ненужные символы, используя регулярные выражения, для iOS и не только…