C#游程编码代码报错:System.ArgumentOutOfRangeException排查求助
排查C#游程编码代码中的System.ArgumentOutOfRangeException异常
首先,咱们来拆解你遇到的问题:你抛出的System.ArgumentOutOfRangeException是因为**Substring方法的参数使用错误**,同时代码里还有几个会导致逻辑失效的问题,我来逐一说明:
1. 异常的直接原因:Substring的长度参数错误
在你的代码中,这一行是问题核心:
sor[i].Replace(sor[i].Substring(indexholder, q), temporary);
string.Substring(int startIndex, int length)的第二个参数是子字符串的长度,但你传入的q是当前字符段的结束索引(已经自增到下一个不同字符的位置)。正确的长度应该是q - indexholder(也就是counter的值,因为counter本身就是这段相同字符的数量)。
举个例子:处理EEDDDNE中的D段时,indexholder=2,q循环后会走到5(指向字符N),此时你传入Substring(2,5),相当于要从索引2开始取5个字符,但原字符串从索引2开始只有5个字符吗?显然不是——原字符串总长度是7,索引2到4只有3个D,这就导致超出字符串范围,直接抛出异常。
2. 其他隐藏的逻辑错误
除了异常问题,你的代码还有几个会导致编码失败的问题:
- 字符串不可变性:C#里的
string是不可变的,Replace方法不会修改原字符串,只会返回一个新字符串。你必须把Replace的结果赋值回sor[i],否则原数组里的字符串不会有任何变化。 - while循环的索引越界风险:当
q增长到等于字符串长度时,sor[i][q]会直接抛出索引越界异常,所以while循环的条件需要先判断q < sor[i].Length。 - 外层for循环的索引跳过问题:外层for循环的
q会在while循环后自动自增,导致跳过下一个字符。比如处理完一段字符后,q已经指向了下一个不同的字符,外层for循环的q++会让你直接跳过这个字符,导致编码遗漏。
修复后的完整代码
我调整了代码逻辑,用StringBuilder来拼接结果(比多次Replace高效得多,尤其适合处理你提到的13个复杂字符串),同时修复了所有问题:
using System; using System.Text; // 别忘了引入StringBuilder的命名空间 public class Program { public static void Main(string[] args) { string[] sor = new string[] { "EEENKDDDDKKKNNKDK", "EEDDDNE" }; // 去掉了原字符串的多余单引号 char holder; int counter = 0; int indexholder; for (int i = 0; i < sor.Length; i++) { StringBuilder result = new StringBuilder(); int q = 0; while (q < sor[i].Length) { holder = sor[i][q]; indexholder = q; counter = 0; // 先判断索引范围,再比较字符,避免越界 while (q < sor[i].Length && sor[i][q] == holder) { q++; counter++; } // 按照规则拼接结果 if (counter > 1) { result.Append($"{counter}{holder}"); } else { result.Append(holder); } } // 将最终结果赋值回原数组 sor[i] = result.ToString(); // 输出验证编码结果 Console.WriteLine(sor[i]); } Console.ReadLine(); } }
测试结果
运行修复后的代码,两个输入字符串会被正确编码:
EEENKDDDDKKKNNKDK→3ENK4D3K2NKDKEEDDDNE→2E3DNE
内容的提问来源于stack exchange,提问作者Suffer
相关产品推荐
相关产品推荐

