読者です 読者をやめる 読者になる 読者になる

【C++】stringの関数による書き換えについて

ふくともです。

C++でstringに格納した特定の文字だけを変換する、という処理を行おうとしたところコケたのでメモ的に書いておく

 

〜イメージ〜

hogehoge → 変換関数 →h0geh0ge

 

コード

#include <iostream>

#include <string>

using namespace std;

void leet(string, int);    // 変換関数

int main(){
    string str="hogehoge";
    leet(str, (int)str.size());
    cout << str << endl;
    return 0;
}

// 変換関数

void leet(string str, int size){

    for(int i=0;i<size;++i)

        if(str[i]=='o') str[i]='0';

    cout << str << endl;

    return;

};

 

コード自体はすごく簡単

stringオブジェクトと、その文字数(サイズ)を関数に渡す

→先頭から一文字ずつ調べて o があれば 0 に置き換える

 

で、実行結果......

hogehoge

......あれ?

変わってない

 

試験的に関数内部でも出力

#include <iostream>

#include <string>

using namespace std;

void leet(string, int);    // 変換関数

int main(){
    string str="hogehoge";
    leet(str, (int)str.size());
    cout << "main() : " << str << endl;
    return 0;
}

// 変換関数

void leet(string str, int size){

    for(int i=0;i<size;++i)

        if(str[i]=='o') str[i]='0';

    cout << "leet() : " << str << endl;

    return;

};

 

実行結果

leet() : h0geh0ge

main() : hogehoge

 

......書き換えはできてないけど、オブジェクトのコピーはされてるみたい

↓詳しくはここのローカルコピーについて読むといいかと。

qiita.com

 

ローカルコピーさせない、ってやり方もないことはないのかもしれないけどめんどくさそう結構な手間が掛かりそうだから別の方法を。

 

よくよく考えてみると、関数によってコピーされてるってことは関数が終了したらスコープの関係でコピー分のメモリは開放されるから元のオブジェクト直接書き換えなくてもいいよね

 

というわけで、書き換え後のstringオブジェクトを返して、それを元のオブジェクトに上書きしてみる

 

#include <iostream>

#include <string>

using namespace std;

string leet(string, int);    // 変換関数

int main(){
    string str="hogehoge";
    str = leet(str, (int)str.size());
    cout << "main() : " << str << endl;
    return 0;
}

// 変換関数

string leet(string str, int size){

    for(int i=0;i<size;++i)

        if(str[i]=='o') str[i]='0';

    cout << "leet() : " << str << endl;

    return str;

};

 

実行結果

leet() : h0geh0ge

main() : h0geh0ge

 

 

目標達成。

最後に試験的に書いてて必要なくなった部分をコメントアウトor削除したら終了。