如何在Solidity中反转字符串?代码执行异常求助
Solidity字符串反转问题排查 & 正确实现方案
嘿,我来帮你搞定这个字符串反转的问题!你碰到的0:string : ������这种乱码/空结果,大概率是字节数组操作时的索引错误、内存分配不当,或者没处理好字符串的UTF-8编码导致的。Solidity里的string本质就是动态字节数组bytes,但直接操作字节的时候很容易踩坑,咱们一步步来分析。
先说说你遇到的错误原因
你觉得逻辑没问题,但可能不小心踩了这些常见坑:
- 内存数组没正确初始化:比如没给反转后的字节数组分配足够的内存空间,导致写入的内容没法被正确读取
- 索引搞反了或者越界:比如循环时从字符串长度
length而不是length-1开始取字节,结果读的都是空字节,转成string自然就是乱码 - 字节转字符串的环节出错:如果你的字节数组本身就有问题,直接转成string肯定会出问题
基础版:支持ASCII字符的反转实现
如果你的字符串都是ASCII范围内的字符(比如英文、数字,单字节),用这个简单实现就够了,绝对不会出乱码:
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; contract StringReverse { function reverse(string memory _input) public pure returns (string memory) { // 把string转成bytes数组方便操作 bytes memory inputBytes = bytes(_input); uint256 strLength = inputBytes.length; // 给反转后的字节数组分配和原字符串一样长的内存 bytes memory reversedBytes = new bytes(strLength); for (uint256 i = 0; i < strLength; i++) { // 从原数组的末尾往前取字节,放到新数组的开头 reversedBytes[i] = inputBytes[strLength - 1 - i]; } // 把反转后的bytes转成string返回 return string(reversedBytes); } }
测试一下:输入"hello"会返回"olleh",完全正常。
进阶版:支持UTF-8多字节字符的反转
如果你的字符串里有中文、emoji这种多字节的UTF-8字符,上面的单字节反转会破坏编码,直接出乱码。这时候得先识别每个字符的字节长度,再整体反转字符,而不是单个字节:
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; contract UTF8StringReverse { function reverseUTF8(string memory _input) public pure returns (string memory) { bytes memory inputBytes = bytes(_input); uint256 totalLength = inputBytes.length; bytes memory reversedBytes = new bytes(totalLength); uint256 reversedPos = 0; uint256 currentPos = totalLength; while (currentPos > 0) { // 判断当前字符的字节长度:遵循UTF-8编码规则 uint8 byteCount = 1; if (inputBytes[currentPos - 1] >= 0xF0) byteCount = 4; else if (inputBytes[currentPos - 1] >= 0xE0) byteCount = 3; else if (inputBytes[currentPos - 1] >= 0xC0) byteCount = 2; // 防止输入无效的UTF-8字符串 require(currentPos >= byteCount, "Invalid UTF-8 string"); // 把当前字符的所有字节复制到反转数组里 for (uint256 j = 0; j < byteCount; j++) { reversedBytes[reversedPos + j] = inputBytes[currentPos - byteCount + j]; } reversedPos += byteCount; currentPos -= byteCount; } return string(reversedBytes); } }
这个版本可以正确处理中文,比如输入"你好世界"会返回"界世好你",完美解决多字节字符的反转问题。
排查你代码的小建议
- 检查内存分配:确认你有没有给反转后的字节数组分配和原字符串一样长的内存,比如
new bytes(inputBytes.length),没分配的话写入的内容都会丢失 - 核对循环索引:看看是不是从
length-1开始往前遍历,要是从length开始,读的都是数组外面的空字节,转成string就是乱码 - 用简单输入测试:先拿
"test"这种短ASCII字符串测试,看能不能正确反转,先排除编码的问题 - 检查返回类型:确保返回的是
string memory,别直接返回bytes数组(虽然Solidity允许隐式转换,但有时候会出问题)
内容的提问来源于stack exchange,提问作者shahabvshahabi
相关产品推荐
相关产品推荐

