【问题标题】:How to locate and remove these symbols from my reversed string如何从我的反转字符串中定位和删除这些符号
【发布时间】:2021-12-30 23:11:28
【问题描述】:

这是一个奇怪的具体问题,但我需要帮助,因为我很困惑。我正在尝试使用指针来要求用户输入一个字符串,并且输出将打印相反的内容。到目前为止,我已经使用了反向函数并应用了指针。下面是代码现在的样子:

#include <iostream>
using namespace std;

void reverse(char name[])
{
    char *p;
    p = name;

    while (*p != '\0')
    {
        ++p;
    }
    while (*p >= 0)
    {
        cout << *p;
        --p;
    }
}

int main()
{
    char name[100];

    cout << "Please enter a string: ";
    cin.getline(name, sizeof(name));

    cout << "The reverse of the string is: ";

    reverse(name);

    return 0;
}

当我运行程序时,它可以工作,但有一个问题。例如输入的字符串是Stack Overflow,结果如下:

Please enter a string: Stack Overflow
The reverse of the string is:  wolfrevO kcatS    ►☺ ◄                   a 

如您所见,最终输出中出现了这些符号。我尝试找到它的来源,我认为这是因为指针,因为当我为函数使用数组时,它正确打印了没有符号的反转字符串。我在问是否有办法在仍然使用指针的同时删除这些符号?我已经尝试过使用指针创建函数的多种变体,但符号仍然打印在最后。

【问题讨论】:

  • 你希望while (*p &gt;= 0) 做什么?
  • char *p; p = name; 应该写成char *p = name;。代码也可以只使用name,而不是创建本地指针。
  • @Beta 我原以为它会满足字符串反向打印的条件,但正如其他答案所指出的那样,这就是我的错误所在。

标签: c++ string


【解决方案1】:

发生这种垃圾是因为您在字符串的开头没有空终止字符,因此您在向后退时不会终止。我修改了您的代码以将前哨零字符保持在第 0 个位置,现在您的代码可以正常工作。

同样条件while (*p &gt;= 0) 应替换为while (*p)

Try it online!

#include <iostream>
using namespace std;

void reverse(char name[])
{
    char *p;
    p = name;

    while (*p != '\0')
    {
        ++p;
    }
    --p;
    while (*p)
    {
        cout << *p;
        --p;
    }
}

int main()
{
    char name[100];
    name[0] = 0;

    cout << "Please enter a string: ";
    cin.getline(name + 1, sizeof(name) - 1);

    cout << "The reverse of the string is: ";

    reverse(name + 1);

    return 0;
}

输入:

Please enter a string: Stack Overflow

输出:

The reverse of the string is: wolfrevO kcatS

【讨论】:

  • 哦,非常感谢!你是对的,我认为它会在最后一个字符处终止,我没有考虑它停止的条件。我想我对符号的来源太分心了,并试图通过查找源来修改代码。再次感谢您!
【解决方案2】:

当你使用

while (*p >= 0)
{
  cout << *p;
  --p;
}

您似乎假设数组开头之前的空间被负数占用;这不是一个安全的假设,并且循环可以遍历该点,打印该内存区域中发生的任何二进制垃圾。我说它可以, 因为像那样解引用指向未分配空间的指针是未定义的行为。 它可以做任何事情;它可以终止循环,使程序看起来正常工作,它可以打印乱码,它可以让你的计算机崩溃。

如果要在给定字符串的开头停止,请查找给定字符串的开头:

do
{
  --p;
  cout << *p;
}
while (p != name);

【讨论】:

    【解决方案3】:

    您正在向字符串中读取 100 个字符,这意味着也有可能会读取一些垃圾输入缓冲区值。这就是符号的来源。由于您使用的是 char 数组,因此也许可以使用类似这样的东西来代替 getline:

    char c = getchar();
    int i = 0;
    while(c != '\n'){
        name[i] = c;
        c= getchar();
        i++;
    }
    name[i++] = '\0'
    

    这样您将只阅读您需要阅读的内容,并且在字符串的末尾会有终止字符 '\0'。请记住,使用 getline 可能有一个更清洁的解决方案。无论哪种方式,问题是您读取的值比您想要读入 char 数组的值多,并且由于您直接访问内存,您需要找出一种在所需字符串之后添加 '\0' 的方法,所以该方法知道何时停止 - 我猜 char 数组的实现方式是为了确保这种情况总是发生,因此它适用于 char 数组但不适用于指针。

    【讨论】:

    • 这是不正确的。符号不是来自字符串结尾之后,而是来自开头之前(如果它们来自任何地方)。
    • 对。感谢指正
    猜你喜欢
    • 2010-09-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多