Почему я не могу использовать побитовый xor для замены символов в строке? - PullRequest
2 голосов
/ 02 июня 2019

Я пытаюсь поменять символы в строке, используя битовые операторы xor вместо заполнителя. Тем не менее, это происходит с ошибками перед выполнением побитового xor. Кто-нибудь может объяснить, почему это так? Есть ли что-то в символах, которые не позволяют мне выполнять побитовые операции?

void reverse(char *str) {
    if (str == NULL || str == '\0') {
        return;
    }

    //Obtain length of str
    int length = 0;
    for (char *ptr = str; *ptr != '\0'; ptr++) {
        length++;
    }

    //Swap
    for (int i = 0; i < (int)(length / 2); i++) {
        str[i] ^= str[length - 1 - i];
        str[length - 1 - i] ^= str[i];
        str[i] ^= str[length - 1 - i];
    }
}

int main() {
    char *str = "bananas";
    reverse(str);
    printf("%s\n", str);

    return 0;
}

Ответы [ 2 ]

4 голосов
/ 02 июня 2019

Строковые литералы читаются только на C. Ну, не совсем, но на практике они есть.Поэтому измените

char* str = "bananas";

на

char str[] = "bananas"; // Store as an array and not a pointer

или

char* str = strdup("bananas"); // Dynamically allocate. Don't forget to free

. Это один из случаев, когда становится очевидным, что массивы не являются указателями

Стандарт не предусматривает, что строковые литералы только для чтения, но с другой стороны, он также не говорит об обратном.И на практике строковые литералы оказываются в области только для чтения в большинстве реализаций Си.Технически они имеют тип char[], что подразумевает, что их следует изменять, но изменение (или попытка изменить) их является неопределенным поведением, поэтому избегайте этого.

http://port70.net/~nsz/c/c11/n1570.html#6.4.5p7

Если программа пытается изменить такой массив, поведение не определено.

Три других комментария о вашем коде:

  1. Приведение в (int)(length / 2) совершенно не нужно.Просто напишите length / 2, поскольку это уже целое число.

  2. Не нужно писать собственную функцию для определения длины строки.Просто напишите length = strlen(str).

  3. Пропустить return 0.Используйте оператор return только в main, если вы хотите выйти до конца или если вы хотите вернуть что-то отличное от 0. Это было нормально с C99.

1 голос
/ 02 июня 2019

Вместо указателя используйте массив

char str[] = "bananas';

Вы не можете изменить строковый литерал, но вы можете изменить массив.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...