I tried debugging for a long time, but I can’t correctly omit consecutive repeat characters

Asked

Viewed 36 times

2

I’m trying to create code to omit repeated characters in a row. I don’t know what’s going on and I’ve tried debugging for hours. Anyway, I’m trying to locate occurrences of consecutive repeated characters and then count more. My code sucks. How can I fix this?

#include <stdio.h>
#include <string.h>
int main(int argc, char *argv[]) {
    char Str[] = "gggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggghggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggg";
    unsigned long Len = strlen(Str);
    /*for (unsigned long Pos = 0; Str[Pos]; Pos++) {
        if (Str[Pos] >= 'A' && Str[Pos] <= 'Z') {
            Str[Pos] += 'a'-'A';
        } else if (Str[Pos] < 0) {
            Str[Pos] = '_';
            Len++;
        } else {
            switch (Str[Pos]) {
                case '@':
                    Str[Pos] = 'a';
                    break;
                case '8':
                    Str[Pos] = 'b';
                    break;
                case '(':
                    Str[Pos] = 'c';
                    break;
                case '3':
                    Str[Pos] = 'e';
                    break;
                case '#':
                    Str[Pos] = 'h';
                    break;
                case '1':
                case '!':
                    Str[Pos] = 'i';
                    break;
                case '&':
                    Str[Pos] = 'k';
                    break;
                case '0':
                    Str[Pos] = 'o';
                    break;
                case '?':
                    Str[Pos] = 'p';
                    break;
                case '5':
                case '$':
                    Str[Pos] = 's';
                    break;
                case '7':
                case '+':
                    Str[Pos] = 't';
                    break;
            }
        }
    }*/ //Não é relevante
    char PrevChar = *Str;
    unsigned long Pos = 1;
    while (Pos < Len) {
        register unsigned long RChars = 0;
        for (; Str[Pos+RChars] == PrevChar; RChars++);
        if (RChars) {
            memmove(Str+Pos, Str+Pos+RChars, (Len-=(RChars))-Pos);
        }
        if (!Str[RChars+Pos]) {
            break;
        }
        PrevChar = Str[Pos];
        Pos++;
    }
    Str[Pos] = '\0';

    puts(Str);
    return 0;
}

Upshot:

Terminated due to signal: SEGMENTATION FAULT (11)
264, 401, 666
s18446744073709551479, 399, 265

I see how long I try to solve my problem and I managed to put my head on the table, on the floor and on the wall underneath me, because it makes me want to cry.

1 answer

0

I rewrote your show like this:

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

void elimina_seguidos_repetidos(char *dst, const char *src) {
    char ultimo = 0;
    int i = 0, j = 0;
    while (1) {
        char c = src[i];
        if (!c) break;
        if (c != ultimo) {
            dst[j] = c;
            j++;
            ultimo = c;
        }
        i++;
    }
    dst[j] = 0;
}

int main(void) {
    char *entrada = "ggggggghgggg";
    char novo[sizeof(entrada)];
    printf("Entrada: %s\n", entrada, novo);
    elimina_seguidos_repetidos(novo, entrada);
    printf("Entrada: %s Novo: %s\n", entrada, novo);
    char entrada2[50];
    strcpy(entrada2, "aaaaabaaaabaaabbbcaa");
    printf("Antes: %s\n", entrada2);
    elimina_seguidos_repetidos(entrada2, entrada2);
    printf("Depois: %s\n", entrada2);
    return 0;
}

The idea is that the function elimina_seguidos_repetidos works with two parameters, respectively the target string and the source string, in the same way as the functions do strcpy and strcat. It also works if the two strings are one, then modifying the given string.

See here working on ideone.

One error your original code had was trying to modify strings created by the compiler (such as that "gggggg ... "). These strings have memory protection against writing. Trying to modify them will cause a segmentation failure. That’s why in the code above I write only in the variables novo and entrada2, but never in entrada which is the string constant "ggggggghgggg". Already the string "aaaaabaaaabaaabbbcaa" is copied by means of strcpy for entrada2, so that she too will never be changed.

To demonstrate this problem, see this code here:

#include <stdio.h>

int main(void) {
    char *foo = "abcdefg";
    foo[1] = 'x';
    printf("%s", foo);
    return 0;
}

He tries to change the constant string "abcdefg", and so makes a mistake. See this one giving error in ideone.

  • thank you!!!!!!!!!!!

  • @Asadefa If this answer solved your problem and you have no further questions, click the " " on the left of the answer to mark it as accepted/correct, which also marks your question as solved/answered. Otherwise, feel free to comment.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.