Реверсирование строки / последовательности символов с использованием только указателей - PullRequest
0 голосов
/ 21 апреля 2011

Я работаю над заданием, которое требует от меня обратить последовательность символов любого типа, используя указатель на «перед» последовательности и указатель на «конец» последовательности.

В моей текущей сборке я сначала пытаюсь переключить символы "front" и "end".Тем не менее, я получаю «нарушение доступа» во время выполнения.

Мой код на данный момент:

#include <cstdlib>
#include <string>
#include <iostream>
using namespace std;

class StrReverse
{
public:
    StrReverse(); //default constructor

    void revStr(); //reverses a given c-string
private:
    typedef char* CharPtr;
    CharPtr front;
    CharPtr end;
    CharPtr cStr;
};

int main()
{
    StrReverse temp = StrReverse();
    temp.revStr();
    system("pause");

    return 0;
}

//default constructor
StrReverse::StrReverse()
{
    cStr = "aDb3EfgZ";
    front = new char;
    end = new char;
}

//reverses a given string
void StrReverse::revStr()
{
    for(int i = 0;i < 4;i++)
    {
        front = (cStr + i);
        end = (cStr + (7 - i));
        *front = *end;
    }
}

Основное ограничение этой проблемы заключается в том, что обращение должно быть выполнено с использованием указателей.Я понимаю, что просто перевернуть строку тривиально, но это ограничение заставляет меня чесать голову.Буду признателен за любые конструктивные комментарии!

Ответы [ 4 ]

2 голосов
/ 21 апреля 2011

Строковый литерал "aDb3EfgZ" назначается cStr, и строковые литералы не могут быть изменены.Ваш компилятор, скорее всего, хранит строковый литерал в постоянном запоминающем устройстве, и при попытке записи в *front из-за этого возникает нарушение прав доступа.

Чтобы получить изменяемую строку, сделайте копию литерала,Например:

const char *cLit = "aDb3EfgZ";
cStr = new char[strlen(cLit)+1];
strcpy(cStr, cLit);

Подробнее см., Например, этот вопрос и вопросы, упомянутые в разделе «Связано».

1 голос
/ 21 апреля 2011

Есть несколько проблем с вашим кодом. Для начала, почему класс; это то, что я ожидал бы сделать с помощью простой функции:

void reverse( char* begin, char* end );

И вам не нужен индекс, так как у вас уже есть указатели; вы можно просто увеличивать и уменьшать указатели.

Кроме того, почему вы выделяете память в своем конструкторе. Память о том, что ты никогда не используйте (или бесплатно).

Наконец, вы действительно ничего не инвертируете в своем цикле. Вам нужно поменяйте местами символы, а не просто скопируйте в конце начало.

А что касается нарушения прав доступа: строковый литерал является константой. Вы не могу изменить это. Если вы хотите сделать обратное на месте, вам нужно скопируйте строку в другое место (или используйте ее для инициализации массива).

0 голосов
/ 22 апреля 2011

Базовая техника обращения на месте:

  • получить указатель (назовите его «влево») на первый символ в строке.
  • получить указатель (назовите его «вправо») до последнего символа в строке (не считая завершающего символа NUL)
  • , в то время как левый указатель меньше правого указателя
    • поменять местами символы, расположенные каждым указателем
    • увеличить левый указатель
    • уменьшить правый указатель

Вот и все, что нужно сделать.Производство обратной копии строки требует немного больше работы.

0 голосов
/ 21 апреля 2011

Ваш конструктор будет пропускать память, потому что вы теряете указатели, которые вы выделяете front и end, эти выделения даже не нужны.Что касается вашей проблемы, вы можете зациклить строку, чтобы найти конец, используя while(*endptr) endptr++;, оттуда размер строки равен endptr - startptr;, который вы используете для выделения временного буфера, чтобы вы могли выполнить while(startptr != endptr) *tempbuf++ = *endptr--; и затем освободить старыйстрока и установить временный буфер в качестве новой строки

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