【问题标题】:Reversing a string/sequence of characters using only pointers仅使用指针反转字符串/字符序列
【发布时间】:2011-04-21 17:11:04
【问题描述】:

我正在做一个任务,需要自己反转一个字符序列,可以是任何给定类型,使用指向序列“前端”的指针和指向序列“结束”的指针.

在我当前的构建中,我首先尝试切换“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;
    }
}

这个问题的关键限制是反转必须使用指针来完成。我意识到简单地反转字符串是微不足道的,但这个限制让我摸不着头脑。任何有建设性的 cmets 将不胜感激!

【问题讨论】:

  • 你为什么要用这个来上课?反转字符串是一个简单的动作,它应该是一个函数。
  • 初学者的错误,我的 C++ 经验一直被 OOP 支配。不过,我现在只是将其缩短为一个功能,谢谢您的帮助!

标签: c++ arrays string pointers


【解决方案1】:

您将字符串文字"aDb3EfgZ" 分配给cStr,并且字符串文字无法修改。您的编译器很可能将字符串文字存储在只读内存中,当您尝试写入 *front 时,您会因此遇到访问冲突。

要获得可修改的字符串,请复制文字。例如:

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

如需了解更多详情,请参阅 this question 以及“已链接”部分中提到的那些。

【讨论】:

  • 或者只是char cStr[] = "aDb3EfgZ";
  • 我认为那是为了算法,而不是为了数据。 "aDb3EfgZ" 是一个数组,不管你怎么切;我希望他会打电话给reverse( cStr, cStr + strlen(cStr) ) 来调用算法。 S
  • 这正是我想要的!非常感谢
【解决方案2】:

您的代码存在几个问题。首先,为什么要上课; 这是我希望用一个简单的功能来完成的事情:

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

而且你不需要索引,因为你已经有了指针;你 可以只增加和减少指针。

另外,为什么要在构造函数中分配内存。你的记忆 永远不要使用(或免费)。

最后,您实际上并没有在循环中反转任何内容。你需要 交换字符,而不仅仅是将末尾的字符复制到 开始。

关于访问冲突:字符串文字是一个常量。你 不能修改它。如果你想在原地做相反的事情,你需要 将字符串复制到其他地方(或使用它来初始化数组)。

【讨论】:

  • 我取消了类,现在将代码缩短为一个函数,初学者错误。我曾计划编写一个析构函数,但主要障碍是访问冲突。但是,复制字符串已经解决了所有问题,感谢您的帮助!
【解决方案3】:

您的构造函数会泄漏内存,因为您丢失了分配前端和末端的指针,甚至不需要这些分配。至于你的问题,你可以使用while(*endptr) endptr++;循环遍历字符串以找到结尾,从那里字符串的大小是endptr - startptr;,你可以用它来分配一个临时缓冲区,这样你就可以做while(startptr != endptr) *tempbuf++ = *endptr--;然后释放旧的字符串并将临时缓冲区设置为新字符串

【讨论】:

  • 这增加了代码的可移植性,感谢您的帮助!
【解决方案4】:

就地反转的基本技术:

  • 获取指向字符串中第一个字符的指针(称为“左”)。
  • 获取指向字符串中最后一个字符(不包括尾随 NUL 字符)的指针(称其为 'right')
  • 当左指针小于右指针时
    • 交换每个指针定位的字符
    • 增加左指针
    • 递减右指针

这就是它的全部内容。生成字符串的反向副本需要更多的工作。

【讨论】:

    猜你喜欢
    • 2021-01-14
    • 2012-05-05
    • 1970-01-01
    • 1970-01-01
    • 2015-10-19
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多