Удаление начала массива 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';
Если вы настаиваете на том, чтобы не использовать 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.