Удалить повторяющиеся символы из символьного массива с++

Стоит задача удалить повторяющиеся символы с массива символов. То есть , если имеем "aabbccdd" , должно получиться "abcd". Написал вот такой вот код , который показался мне абсолютно правильным но некоторые символы все равно повторяются дважды , а то и трижды. m- количество символов , temp - сам массив. Просьба не осуждать за наличие глупых ошибок (если таковы будут).

UPD:

Поскольку не совсем точно описал проблему , добавлю , что во всей строке символ может появляться однажды. То есть строка "abcdeabcdeabcde" на выходе будет "abcde". Спасибо всем кто откликнулся на мой вопрос!

for (int i = 0; i < m; i++) {
        for (int j = 0; j < m; j++) {
            if (i == j) continue;
            if (temp[i] == temp[j]) {
                for (int k = i; k < m; k++) {
                    temp[k] = temp[k + 1];
                }
                m--;
                continue;
            }
        }
    }

Ответы (3 шт):

Автор решения: Harry

Ну, я бы делал примерно так:

char s[] = "aabcccddegfhtttj";

for(char last = *s, *f = s, *l = s;;)
{
    while(*l == last) l++;
    last = *++f = *l;
    if (*l == 0) { *f = 0; break; }
}

cout << s;
→ Ссылка
Автор решения: TigerTV.ru

Используем map:

#include <iostream>
#include <map>

int main() {

    char temp[] = "aabbccddeeaaaaaffffmmmmekkkk";
    std::cout << temp << std::endl; 

    std::map<char,bool> m;
    for(char *it = temp; *it != '\0'; ++it) {
        m[*it] = true;
    }

    char* write = temp;
    for(auto it: m) {
        *write++ = it.first;
    }
    *write = '\0';

    std::cout << temp << std::endl; 
}

// aabbccddeeaaaaaffffmmmmekkkk
// abcdefkm

Варианты с заменой повторяющихся символов находящихся друг с другом:

С указателями:

#include <iostream>

int main() {

    char temp[] = "aabbccddeeaaaaaffffmmmmekkkk";
    std::cout << temp << std::endl;

    char* write = temp;
    for(char* read = temp + 1; *read != '\0'; ++read) {
        if(*read != *write) *++write = *read;
    }
    *++write = '\0';

    std::cout << temp << std::endl;
}

// aabbccddeeaaaaaffffmmmmekkkk
// abcdeafmek

или через индексы массива:

#include <iostream>
#include <cstring>

int main() {

    char temp[] = "aabbccddeeaaaaaffffmmmmekkkk";
    std::cout << temp << std::endl;

    int m = strlen(temp);
    int j = 0;
    for(int i = 1; i < m; ++i) {
        if(temp[i] != temp[j]) temp[++j] = temp[i]; 
    }
    temp[++j] = '\0';
    std::cout << temp << std::endl;
}

// aabbccddeeaaaaaffffmmmmekkkk
// abcdeafmek
→ Ссылка
Автор решения: avp

Если рассматривать только однобайтные кодировки и требуется оставить лишь первое вхождение символа, то можно вот так:

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

int
main (int ac, char *av[])
{
  char str[10240];

  while (fgets(str, 10240, stdin)) {
    int chars[256] = {0};  // множество встреченных символов, код символа это индекс в данном массиве
    int n = 0;  // количесво символов в массиве после удаления дубликатов

    for (int i = 0; str[i]; i++) {
      int chix = (unsigned char)str[i];
      if (chars[chix] == 0)
         str[n++] = str[i];  // такой символ встретился впервые
      chars[chix]++;
    }
    str[n] = 0;
    
    puts(str);
    
  }
  
  return puts("End") == EOF;
}
→ Ссылка