Solidity
Solidity 將逗號分隔的字元串拆分為單個單詞
由於
Solidity
函式不能接受String Arrays
作為參數,因此我嘗試傳入一個以逗號分隔的長字元串,然後即時將其轉換為字元串數組。我很接近 - 但
else
聲明中的底部一行 - 我在評論中指出 - 不斷破壞契約。這是我的程式碼:
function splitString(string calldata stringToSplit) external pure returns(string memory) { // 1. Declare a string array to hold all the individual words I'm able to tease // out of the passed-in string: string[] memory finalWordsArray; // 2. Declare a word-counter var to keep track of how many words I've gotten: uint256 wordCounter = 0; // 3. Convert and store the passed-in String argument into a Bytes Array so // I can iterate through it one character at a time: bytes memory stringAsBytesArray = bytes(stringToSplit); // 4. Declare another bytes array to contain all the characters that will be // in my next full individual Word: string memory tmp = new string(stringAsBytesArray.length); bytes memory tempWord = bytes(tmp); // 5. Iterate through the "stringAsBytesArray" one Char at a time: // ["Hello,here,we,are,today"] for(uint i = 0; i < stringAsBytesArray.length; i++) { // if current char is NOT a comma, append it to my "tempWord": if (stringAsBytesArray[i] != ",") { tempWord[i] = stringAsBytesArray[i]; } else { // We found a Comma, which means we've reached the end of a word. So // let's convert our "tempWord" from a bytes Array to a String: string memory newWord = string(tempWord); // And then add that word to our "finalWordsArray": // -->this next line causes a crash! // finalWordsArray[wordCounter] = newWord; // Iterate our wordCounter: wordCounter++; // And reset/blank-out our "tempWord" for the next go-around: tempWord = bytes(tmp); // This next statement DOES work: it returns the first word it // found before hitting that first comma. I put this in just to // see that I am getting at least SOMETHING out of this: return newWord; } } return "no Commas found!!!"; // return string(finalWordsArray[2]); }
由於 Solidity 函式不能接受字元串數組作為參數
這在技術上並不能回答您的問題,但如果您啟用
ABIEncoderV2
,您可以簡單地將字元串數組傳遞給函式,而不是嘗試自己拆分它。就氣體使用而言,這可能更有效。例如:
pragma solidity ^0.7.4; pragma experimental ABIEncoderV2; contract Foo { function bar (string[] calldata baz) public { // do something with `baz` here } }
問題是它
finalWordsArray
永遠不會被分配,所以它是空的,你不能將項目分配給任何索引。為了使分配起作用,您必須分配finalWordsArray
足夠的條目。不幸的是,記憶體數組不是動態的,一旦初始化就不能改變它的長度。可能最好的選擇是像@Morten 所說的那樣使用 ABIEncoverV2 或使用solidity -stringutils來避免手動解析。