#include <iostream>
#include <string>
using namespace std;
int main()
{
string s1;
cin>>s1;
int n=s1.size();
string s2;
for(int a=0;a<n;a++)
{
s2[a]=s1[n-1-a];
}
cout<<s2;
}
Run Code Online (Sandbox Code Playgroud)
但是我没有得到任何输出,但我可以打印反转字符串的元素.任何人都可以帮忙.
string s2; // no size allocated
for(int a=0;a<n;a++)
{
s2[a]=s1[n-1-a]; // write to somewhere in s2 that doesn't exist yet
Run Code Online (Sandbox Code Playgroud)
您正在写入s2您从未创建过的元素.这是未定义的行为,任何事情都可能发生,包括看似正常工作.在这种情况下,您可能会覆盖内存中的一些随机位置.它可能会崩溃,或者内存可能确实存在,但不会立即破坏任何其他内容.你甚至可以在以后阅读它,但它似乎只能通过纯粹的意外工作.
您可以通过始终使用s2.at(a)访问数据来捕获此问题,因为它将为您进行范围检查.([]不进行范围检查).当然,这是一个成本,有时人们会在他们确定索引不能超出范围的情况下跳过它.这是有争议的.在这种情况下,即使你可能确定你的数学是正确的,它仍然可以帮助捕获这个bug.
您需要预先创建该空间,即创建一个充满正确数量的虚拟值的字符串,或者根据需要为每个元素创建空间push_back.我可能会选择第一个选项:
string s2(s1.size(), '\0'); // fill with the right number of NULs
for(int a=0;a<n;a++)
{
s2.at(a)=s1.at(n-1-a); // overwrite the NULs
Run Code Online (Sandbox Code Playgroud)
例如,您可能希望选择一个未出现在测试数据中的可打印虚拟字符'#',因为如果您无法正确覆盖某些元素,则在打印出来时它会变得非常明显.例如,如果你试图反转,"abc"但是当你打印出来时,你"cb#"会明白你有一些一个一个错误.
第二个选项有点贵,因为它可能需要在字符串增长时进行多次分配和复制,但是它的外观如下:
string s2; // no space allocated yet
for(int a=0;a<n;a++)
{
s2.push_back(s1.at(n-1-a)); // create space on demand
Run Code Online (Sandbox Code Playgroud)
我假设你这样做是为了学习练习,但我建议你不要写自己的reverse,因为语言是在库中提供的.