Ответ на вопрос.
Ваш код переусложнён, но если в нём разбираться, то проблема с циклом, в котором идут проверки с z.
for (o = i,l = j; ;l++)
{
if (s[o] == s[l])
{
z++;
}
else
{
z=0;
break;
}
// Итак, что произойдёт в if'е ниже. Каждый раз, когда z > 3, будет добавляться строка в массив
// Даже если текущая последовательность ещё не кончилась.
if (z > 3)
{
for (q = 0; q < z; q++)
{
c[k][q] = s[l];
}
c[k][q] = '\0';
k++;
i = l + q;
}
}
Теперь по рекомендациям по коду.
Во-первых, старайтесь давать переменным осмысленные названия. Например, z могла бы называться current_sequence_length. Так проще отлаживаться и вообще понимать, что происходит.
Во-вторых, не экономьте на пробелах вокруг присваиваний, арифметических операторов и знаков равенства.
https://google.github.io/styleguide/cppguide.html - довольно хороший стайлгайд.
3. Как уже упомянули, можно было бы использовать строки, которые string, и встроенные фичи.
4. Если без алгоритмов поиска и строк - всё равно ваше решение слишком сложное, его можно упростить.
В качестве наброскаint start_pos = 0;
int cur_pos = 1;
while (cur_pos < len)
{
// Начинаем сравнивать
while (cur_pos < len && s[start_pos] == s[cur_pos])
{
// Просто двигаемся к следующему элементу, пока они одинаковые
++cur_pos;
}
if (cur_pos - start_pos > 3) // Нашлось 4 или более одинаковых символа подряд
{
// Копируем, мне слишком лень писать этот кусок :) Но тут надо корректно обработать
// ситуацию с концом строки
// А ещё не забываем подвинуть start_pos и cur_pos
start_pos = cur_pos;
++cur_pos;
}
}
Можно вообще без вложенных циклов, можно ещё как-то иначе. Я про примерную суть.