【问题标题】:what am i doing wrong?reverse string c++我在做什么错?反向字符串 C++
【发布时间】:2020-04-17 19:02:34
【问题描述】:

所以我想在 c++ 中做最简单的事情,反转一个字符串(存储新字符串)然后打印它

我的代码是:

char a[size] , reverse[size];
strcpy(a,"dlow olleh " );
for (int i = 0 ;  i <= strlen(a); i++) {
   reverse[i]= a[strlen(a)-i];
}
cout << reverse ;

我必须注意,当 cout

【问题讨论】:

  • 你可能忘记了reverse中的空终止符
  • 我是 c++ 新手,一般是编程,您介意详细说明一下吗?
  • C 风格的“字符串”(char 数组)有一个空终止符 \0,它指示字符串的结束位置。再三考虑,您的反转代码将该空终止符放在reverse 的第一个字符处,因此当您尝试打印它时,它会立即到达“结尾”
  • 你真是个天才
  • @YarinShani 请注意,std::strlen() 是一个从 char* 开始搜索直到找到 \0' 的函数 - 每次调用它。在你的例子中有很多电话。建议:在循环前调用一次,将结果存储并在循环中使用。

标签: c++ string for-loop reverse c-strings


【解决方案1】:

我做错了什么?

您正在使用 char 的数组和 C 标准库的函数来操作 C++ 中的字符串。

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

int main()
{
    std::string foo{ "Hello, World!" };
    std::string bar{ foo };
    std::reverse(bar.begin(), bar.end());
    std::cout << '\"' << foo << "\" ==> \"" << bar << "\"\n";
}

如果——出于某种我无法理解的原因——您*必须*步行完成,请以惯用的方式进行并提供一个带有一对迭代器的接口:

#include <algorithm>

void str_reverse(char *begin, char *end)
{
    while (begin < end)
        std::swap(*begin++, *--end);
}

// ...

#include <cstring>
// ...
char foo[]{ "Hello, World!" };
str_reverse(foo, foo + std::strlen(foo));

如果您出于某种原因不能使用&lt;algorithm&gt;,请实现您自己的swap()

template<typename T>
void swap(T &a, T &b)
{
    T tmp{ a };
    a = b;
    b = tmp;
}

【讨论】:

  • 更简单:std::string bar{ foo.rbegin(), foo.rend() };.
  • @J. Doe “你正在使用 C 的 char 数组和函数” 这没有错。他正在学习如何处理包含字符串的字符数组。这是每个人都应该知道的语言的重要组成部分。
  • @VladfromMoscow 这是语言的重要组成部分——我完全不同意。唯一重要的是要知道何时必须与某些 C 样式库进行交互。但是在 C++ 中使用 C 风格的字符串函数几乎没有充分的理由。
【解决方案2】:

在这个循环中

for (int i = 0 ;  i <= strlen(a); i++){
       reverse[i]= a[strlen(a)-i];

您访问的字符超出了字符串的实际字符。

例如,当 i 等于 0 时,您将字符串 a 中的终止零字符处理到字符串 reverse 的第一个位置。

reverse[0]= a[strlen(a)-0];

代码可以编写得更简单,例如无需对函数 strlen 进行冗余调用。

char a[size], reverse[size];
strcpy( a, "dlrow olleh" );

size_t i = 0;
for ( size_t n = strlen( a ); i < n; i++ ) 
{
    reverse[i] = a[n - i - 1];
}
reverse[i] = '\0';

std::cout << reverse << '\n';

注意有标准算法std::reverse_copy 可以完成相同的任务。

下面是演示程序。

#include <iostream>
#include <algorithm>
#include <cstring>

int main() 
{
    const size_t SIZE = 20;
    char a[SIZE], reverse[SIZE];

    std::strcpy( a, "dlrow olleh" );    

    std::cout << a <<'\n';

    auto it = std::reverse_copy( a, a + strlen( a ), reverse );
    *it = '\0';

    std::cout << reverse <<'\n';

    return 0;
}

程序输出是

dlrow olleh
hello world

【讨论】:

  • 考虑使用strcpy_s 而不是strcpy
  • strcpy_s 仅略好于strcpy。它所做的只是在超出范围时强制调用处理程序(通常会中止程序),但是您 A)必须告诉它边界是什么并且是正确的,并且 B)可能仍然有一个程序崩溃。虽然失败更好,但你根本不想失败。使用std::string
【解决方案3】:

您在反转字符串时复制的第一个实际上是空终止符,因此当您将其打印到控制台时它不会显示,因为空终止符是数组中的第一个,所以您想要这样做

int size = 12;
char a[12], reverse[12];
strcpy(a, "dlow olleh ");
for (int i = 0; i < strlen(a); i++) {
    reverse[i] = a[strlen(a) - (i+1)];
}
reverse[strlen(a)] = '\0';
cout << reverse;

【讨论】:

  • 是的,完全正确,我按照你的建议编辑了代码@DavidSchwartz
猜你喜欢
  • 1970-01-01
  • 2011-05-08
  • 1970-01-01
  • 2013-04-15
  • 1970-01-01
  • 2020-12-27
  • 2012-08-24
  • 1970-01-01
  • 2014-11-16
相关资源
最近更新 更多