C++ 尝试反转字符时出现意外输出*

C++ 尝试反转字符时出现意外输出*,c++,string,algorithm,coding-style,reverse,C++,String,Algorithm,Coding Style,Reverse,当我试着运行它时,我得到了一些疯狂的输出,我的电脑开始发出嘟嘟声。我在这里明显做错了什么?C字符串的末尾用字符“\0”标记。您使用了“\n”,这是。您的意思是,除了使用裸漏新的、不推荐使用的char*而不是const char*或更好的std::string,而不是使用标准的库算法std::reverse,将IO与算法混合,并包含整个名称空间std,这可能会间接地将std::reverse引入范围,而不会将自己的reverse放在自己的名称空间中 #include<iostream>

当我试着运行它时,我得到了一些疯狂的输出,我的电脑开始发出嘟嘟声。我在这里明显做错了什么?

C字符串的末尾用字符“\0”标记。您使用了“\n”,这是。

您的意思是,除了使用裸漏新的、不推荐使用的char*而不是const char*或更好的std::string,而不是使用标准的库算法std::reverse,将IO与算法混合,并包含整个名称空间std,这可能会间接地将std::reverse引入范围,而不会将自己的reverse放在自己的名称空间中

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

void reverse(char* str)
{
    char *new_str = str;
    while(*new_str != '\n'){
        new_str++;
    }
    while(new_str != str){
        cout << *new_str;
        new_str--;
    }
    cout << *new_str;
}

int main()
{
    char *str = new char[1024];
    str = "hello world";

    reverse(str);
}
如果您只对如何编写反向算法感兴趣,这里不依赖于您有空终止符这一事实:

#include <algorithm>
#include <iostream>
#include <iterator>
#include <string>

// using namespace std; // for the brave, and drop the std:: in the next 3 lines

int main()
{
    std::string str = "hello world";    // std::string instead of char*
    std::reverse(begin(str), end(str)); // standard library algorithm
    std::cout << str;                   // IO separate from algorithm
}

问题是,首先,您分配了分配内存的地址,然后将它重新分配给具有C++中的类型const char []的点到字符串文本。

template<class BidirIt>
void reverse(BidirIt first, BidirIt last)
{
    while ((first != last) && (first != --last)) {
        std::swap(*first++, *last);
    }
}
此字符串文字具有终止字符“\0”。它没有新行字符'\n'。因此,函数无效,因为它将尝试访问数组以外的内存,搜索新行字符

有效的代码可以如下所示

char *str = new char[1024];
str = "hello world";
或者,如果您希望自己以交互方式输入字符串,那么main可以如下所示

#include <iostream>
using namespace std;

void reverse( const char* s )
{
    const char *p = s;

    while ( *p ) p++;

    while ( p != s ) cout << *--p;
}

int main()
{
    const char *s = "hello world";

    reverse( s );
}

纠正您的功能:

int main()
{
    const size_t N = 1024;
    char s[N];

    cout << "Enter a statement: ";
    cin.getline( s, N );

    reverse( s );
}

这么简单。非常感谢。你知道为什么我会收到一条警告,告诉我从字符串常量到“char*”的转换不推荐使用。我知道这是因为str=你好世界;但这只是一个我可以忽略的警告吗?是的,因为您使用的是字符串常量,所以应该使用const char*而不是char*。常量表示指向的数据是常量。此外,main中的前两行应替换为常量char*str=hello world;。不需要为字符串常量分配,编译器会为您分配。啊,好的。再次感谢你!这也是一个内存泄漏,因为新的d数组指针丢失且从未使用过。@DarkWanderer不要让我开始:定义你自己的反向函数,如果意外地还包括,那么你将面临严重的ADL错误。我知道如何使用STL。反向字符*是面试类型的问题,所以你的回答对我没有帮助。谢谢,但不谢谢。@user3150601您没有给出上下文。但即便如此:您仍然可以使用与std::reverse相同的签名,使用两个迭代器,而不是依赖于隐式空终止符。例如,如果要求您反转std::vector,那么您必须更改整个算法。您还可以将IO与算法本身分离。模仿STL仍然比你没有冒犯的帖子更好,但是你问什么是明显错误的,代码永远不应该通过代码审查。那么我发布的技术上是不是不正确?这不是面试官期望看到的吗?我无法想象他们在寻找预定义的反面。看看这个答案中的第一句+评论。此代码存在两个问题,即可能的SEGFULTS、内存泄漏、输出与处理混合等。reverse应重命名为print_reverse?因为它不会反转任何东西。@Jarod42我认为这对于这个简单的练习并不重要。尽管名称颠倒可能会混淆用户。
void reverse(char* str)
{
    char *new_str = str;   
    while(*new_str){ // use this instead of *new_ptr != '\n'
        new_str++;
    }
    while(new_str != str){
        cout << *new_str;
        new_str--;
    }
    cout << *new_str;
}