Вам дан массив символов, который не является строкой C, поскольку может содержать нулевые символы.Это означает, что вы должны забыть все, что вы могли знать о строках Си при обработке.
Он задается двумя указателями, один в начале, один за концом.Поскольку он должен быть обработан на месте, начальный указатель не изменится, поэтому ваша функция должна просто вернуть новый конечный указатель (то же самое определение: один после последнего сохраненного символа).
Как только это будет сказано,Ваш текущий код слишком сложен.Вам нужно только читать строку по одному символу за раз, сравнивать текущий символ с предыдущим и сохранять его, только если они отличаются.Простой способ - использовать 2 указателя, один для чтения и один для записи, увеличивать указатель чтения на каждой итерации и увеличивать указатель записи только в том случае, если необходимо сохранить символ.Что касается предыдущего значения, то идиоматическим способом является его инициализация значением int, которое не может быть представлено символом.
Функция сокращается до:
char *sajat::unique(char *first, char *last){
char *rd = first, *wr = first;
int prev = UCHAR_MAX + 1; // cannot be a character value
while (rd != last) {
if (prev != *rd) {
prev = *wr++ = *rd;
}
rd++;
}
return wr;
}
Демонстрационный код:
#include <iostream>
#include <string>
#include <climits>
char *unique(char *first, char *last){
char *rd = first, *wr = first;
int prev = UCHAR_MAX + 1; // cannot be a character value
while (rd != last) {
if (prev != *rd) {
prev = *wr++ = *rd;
}
rd++;
}
return wr;
}
int main() {
char tst[] = "H\0elllo C+++++ +!#";
char *last = unique(tst, tst+sizeof(tst) - 1); // reject the terminating null
std::cout << std::string(tst, last) << std::endl; // first display the result as a string
for (char *ix=tst;ix<last; ix++) { // then every character in hexa
std::cout << std::hex << " " << (unsigned int)(unsigned char) *ix;
}
std::cout << std::endl;
return 0;
}
В моей системе ASCII это показывает:
Helo C+ +!#
48 0 65 6c 6f 20 43 2b 20 2b 21 23