9
8

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

Solidityで文字列連結

Posted at

どうも。
今回、Solidityで文字列連結をしている方がいらっしゃったのですが(下記リンク)、ライブラリを使っていたため、自力でなんとか実装できないかと挑戦してみました。

Solidityの文字列結合
@bellbelljp さんの記事

実装

MyStringTest.sol
pragma solidity ^0.4.19;

contract MyStringTest {

    function strConnect() public constant returns(string){
        
        string memory str1 = "abc";
        string memory str2 = "def";
        bytes memory strbyte1 = bytes(str1);
        bytes memory strbyte2 = bytes(str2);
        
        bytes memory str = new bytes(strbyte1.length + strbyte2.length);
        
        uint8 point = 0;
        
        for(uint8 j = 0; j < strbyte1.length;j++){
            str[point] = strbyte1[j];
            point++;
        }
        for(uint8 k = 0; k < strbyte2.length;k++){
            str[point] = strbyte2[k];
            point++;
        }
        return string(str);
    }
}

一行ずつ見ていきましょう。

string memory str1 = "abc";
string memory str2 = "def";

bytes memory strbyte1 = bytes(str1);
bytes memory strbyte2 = bytes(str2);

まずここで、"abc"という文字列と"def"という文字列をそれぞれstr1とstr2という変数に代入しています。
そしてその後、string型をbytes型に変換しています。
string型とbytes型は、基本的には同じことができるのですが、string型には.lengthメンバがなかったり、添字を使えなかったりなどと、文字列連結をする上で不便な点があります。なので変換をしています。

bytes memory str = new bytes(strbyte1.length + strbyte2.length);

次に、bytes型のstrという変数を作っています。bytesは動的配列なので、ここでnew句を使ってそれぞれ文字数文のバイトを確保しています。mallocみたいなもんですね。

uint8 point = 0;

for(uint8 j = 0; j < strbyte1.length;j++){
    str[point] = strbyte1[j];
    point++;
}
for(uint8 k = 0; k < strbyte2.length;k++){
    str[point] = strbyte2[k];
    point++;
}

次は、実際の文字列連結です。strのpoint番目の配列、つまりpointバイトの場所に、それぞれstrbyte1とstrbyte2の文字を一文字ずつコピーしていきます。正確に言うと参照のコピーになるのかな…?
あんまりEthereumのポインタがわかっていないのでそこはよくわかりません。
とりあえずこれでstrに連結した文字が代入されました。

return string(str);

最後に、bytes型をstring型に直して値を返しています。


以上、無茶がありましたが結構簡単に実装できました。ちなみに、Solidityの文字列連結のライブラリでは、Library句を使ってstring型自体に文字列連結のメソッドを追加しているようです。興味があったら調べてみてください。

また、今回のコードは、連結する変数が2つと固定していることもあり、あまり汎用的ではありません。
文字列型の配列に、それぞれ文字列を代入して、最後に全部を連結する、なんて実装の仕方をすればもう少し綺麗になると思います。が、今回の記事はそこまで求めていないので妥協しました…。

最後まで閲覧いただき、ありがとうございました!

9
8
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
9
8

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?