Удаление начала массива char при последнем появлении символа C++

Я ищу лучший способ удалить начало строки до последнего вхождения символа. Например. У меня есть массив символов, который содержит следующее:

[Microsoft] [Драйвер ODBC SQL Server][SQL Server] Опция 'enable_debug_reports' требует значения 0 или 1.

По сути, я ищу последнее вхождение ']'. Я хотел бы, чтобы мой массив символов был обрезан до:

Опция 'enable_debug_reports' требует значения 0 или 1.

Я нашел несколько способов сделать это с типом данных строки. Мне интересно, есть ли эффективный способ манипулировать массивом символов. Моя программа требует, чтобы несколько параметров были char[] вместо строк. Как бы я использовал что-то вроде strcpy в моей ситуации?

3 ответа

Решение

Ниже должно работать, если ваша строка содержит символ ']':

std::string trimIt(originalCStr);
std::string trimmed(trimIt.substr(trimIt.find_last_of("]")));
strcpy(originalCStr, trimmed.c_str());

Для чистого подхода C:

char *toPtr = originalCStr;
char *fromPtr = strchr(toPtr, ']');
++fromPtr;
while (*fromPtr != '\0') {
    *toPtr = *fromPtr;
    ++fromPtr;
    ++toPtr;
}
*toPtr = '\0';

Вы можете использовать strrchr, чтобы найти последнее вхождение ']', а затем вырезать ваш char[], используя memcpy, как показано здесь

Если вы настаиваете на том, чтобы не использовать std::stringпо какой-то причине все еще существует чистый подход C++, использующий стандартные алгоритмы, которые прекрасно работают с необработанными массивами. Ниже приведен C++14 (он использует std::rbegin а также std::rend), но вы можете адаптировать его к C++11, используя std::reverse_iterator вручную при необходимости:

#include <algorithm>
#include <iostream>

template <class InputRange, class OutputIterator, class Value>
void CopyFrom(InputRange const& input, OutputIterator output_iter, Value const& value)
{
    using std::rbegin;
    using std::rend;
    using std::end;

    auto const iter_last = std::find(rbegin(input), rend(input), value);
    std::copy(iter_last.base(), end(input), output_iter);
}

int main()
{
    char const src[] = "[Microsoft][ODBC SQL Server Driver][SQL Server]Option 'enable_debug_reports' requires a value of 0 or 1.";
    char * dst = new char[sizeof(src) + 1](); // just for this toy program

    CopyFrom(src, dst, ']');

    std::cout << dst;
    delete[] dst;
}

Обратите внимание, что это решение предполагает, что вам нужна подстрока в качестве копии, и нет проверки ошибок для ввода, который не содержит указанное значение.

И, конечно, вам, вероятно, лучше перейти на std::string и используя c_str() для любых C API.

Другие вопросы по тегам