C ++:按索引更改字符串 [英] C++ : Change string by index

查看:333
本文介绍了C ++:按索引更改字符串的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我是C ++的初学者,我目前正在使用字符串。
我的问题是为什么当编译我在下面提供的脚本时,我可以得到字符串的字符,当我使用索引符号,但不能得到字符串本身使用 cout
这是代码:

  #include< iostream> 
#include< string>

using namespace std;

int main()
{
string original; // original message
string altered; // message with letter-shift

original =abc;
cout<< 原文:<<原始< endl; //显示原始消息

for(int i = 0; i altered [i] = original [i] + 5;

//显示改变的消息
cout<改变的[0] <改变[1]< <改变的[2] endl;
cout<< altered:<改变的< endl;

return 0;
}

当我运行这个脚本时,显示字符串altered正确使用此行:

  cout<改变的[0] <改变[1]< <改变的[2] endl; 

但字符串本身不显示此行:

  cout<< altered:<改变的< endl; 

我想知道为什么会发生这种情况。

c> c> c> c> $ c> string before the循环,因此您的代码显示未定义的行为

  = original [i] + 5; // UB  -  altered is empty 

要修复此问题,请调整 code>之前的循环:

  altered.resize(original.size 

或使用 std :: string :: operator + = 或类似于追加到 changed

  altered + = original [i] + 5;这样,在循环之前它可以是空的,它会自动调整自己的大小以包含附加的字符。



<






说明



UB在这里发生的方式你在成功编写静态数组中的数据, std :: string 用于短字符串优化( std :: string ::如果你通过 std :: string :: size()访问这个数组,但是<$ c> $ c> std :: string :: size()保留 0 ,以及 std :: string :: begin()== std :: string :: end()



这就是为什么你可以单独访问数据,with UB):

  cout<改变的[0] <改变[1]< <改变的[2] endl; 

cout<对于 std ::定义,简化 运算符<

$

  

operator<<<<(std :: ostream& os,std :: string const& str)
{
for(auto it = str.begin(); it!= str.end ++ it)//此循环不运行
os<< *它;

return os;
}

在一句话中, std ::字符串不知道您对其底层数组执行了哪些操作,并且您希望字符串长度增长。






最后,< algoritm> 执行此转换的方式

  std :: transform(original.begin(),original.end(),
std :: back_inserter .begin()如果改变了原来的长度
[](char c)
{
return c + 5;
}

(必填标题:< algorithm> < iterator> ;


i am a beginner in C++ and i am currently working with strings. My question is why when compiling the script i'm providing below, i can get the string's characters when i use index notation, but cannot get the string itself using cout. This is the code:

#include <iostream>
#include <string>

using namespace std;

int main()
{
    string original; // original message
    string altered; // message with letter-shift

    original = "abc";
    cout << "Original : " << original << endl; // display the original message

    for(int i = 0; i<original.size(); i++)
        altered[i] = original[i] + 5;

    // display altered message
    cout << altered[0] << " " << altered[1] << " " << altered[2] << endl;
    cout << "altered : " << altered << endl;

    return 0;
}

When I run this script, the characters in the string "altered" are displayed correctly with this line :

cout << altered[0] << " " << altered[1] << " " << altered[2] << endl;

But the string itself is not displayed with this line :

cout << "altered : " << altered << endl;

I would like to know why this happens.

解决方案

You have not resized your altered string to fit the length of the original string before the loop, thus your code exhibits undefined behavior:

altered[i] = original[i] + 5; // UB -  altered is empty

To fix this, resize altered before the loop:

altered.resize(original.size());

Or use std::string::operator+= or similar to append to altered:

altered += original[i] + 5;

This way, it can be empty before the loop, it will automatically resize itself to contain appended characters.


Explanation

The way UB is happening here, is that you're succeeding in writing the data in the static array, which std::string uses for short string optimization (std::string::operator[] does no checks if you're accessing this array past the std::string::size()), but std::string::size() remains 0, as well as std::string::begin() == std::string::end().

That's why you can access the data individually (again, with UB):

cout << altered[0] << " " << altered[1] << " " << altered[2] << endl;

but cout << aligned does not print anything, considering simplified operator<< definition for std::string looks functionally like this:

std::ostream &operator<<(std::ostream &os, std::string const& str)
{
    for(auto it = str.begin(); it != str.end(); ++it) // this loop does not run
        os << *it;

    return os;
}

In one sentence, std::string is not aware of what you did to its underlying array and that you meant the string to grow in length.


To conclude, <algoritm> way of doing this transformation:

std::transform(original.begin(), original.end(),
    std::back_inserter(altered), // or altered.begin() if altered was resized to original's length
    [](char c)
    {
        return c + 5;
    }

(required headers: <algorithm>, <iterator>)

这篇关于C ++:按索引更改字符串的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆