C# 我想写一个函数,它接受一个字符串,并返回一个至少有3位结尾的字符串

C# 我想写一个函数,它接受一个字符串,并返回一个至少有3位结尾的字符串,c#,unit-testing,C#,Unit Testing,如果传入的字符串末尾已经有3位数字,则返回unchanged。如果传入的字符串末尾没有3位数字,则需要在末尾的任何数字之前插入零,以便有3位数字 我已经在私有静态字符串清理器(string-inputString)中加入了一些逻辑来实现代码,但它会导致以下错误: 测试:'A12'应为:'A012'异常:索引超出数组的边界 测试:'A12345'应为:'A12345'异常:索引超出数组的边界 测试:'A1B3'应为:'A1B003'异常:索引超出数组的边界 测试:“”应为:'000'异常:未将对象

如果传入的字符串末尾已经有3位数字,则返回unchanged。如果传入的字符串末尾没有3位数字,则需要在末尾的任何数字之前插入零,以便有3位数字

我已经在
私有静态字符串清理器(string-inputString)
中加入了一些逻辑来实现代码,但它会导致以下错误:

测试:'A12'应为:'A012'异常:索引超出数组的边界

测试:'A12345'应为:'A12345'异常:索引超出数组的边界

测试:'A1B3'应为:'A1B003'异常:索引超出数组的边界

测试:“”应为:'000'异常:未将对象引用设置为对象的实例

测试:“”应为'000'实际为'000'结果:通过

使用系统;
使用System.Collections.Generic;
使用System.Linq;
使用系统文本;
命名空间ConvertToCamelCases
{
班级计划
{
静态void Main(字符串[]参数)
{
List testValues=新列表()
{
新字符串[]{“A12”,“A012”},
新字符串[]{“A12345”,“A12345”},
新字符串[]{“A1B3”,“A1B003”},
新字符串[]{null,“000”},
新字符串[]{“,“000”}
};
foreach(testValues中的字符串[]testValue)
{
testStringCleaner(testValue[0],testValue[1]);
}
Console.ReadLine();
}
私有静态void testStringCleaner(string inputString、string expectedString)
{
尝试
{
字符串actualString=stringCleaner(inputString);
字符串passOrFail=(实际字符串==expectedString)?“通过”:“失败”;
WriteLine(“测试:{0}预期:{1}实际:{2}结果:{3}”,inputString,expectedString,actualString,passOrFail);
}
捕获(例外情况除外)
{
WriteLine(“测试:{0}预期:{1}异常:{2}”,inputString,expectedString,ex.Message);
}
}
私有静态字符串字符串清理器(字符串输入字符串)
{
字符串结果=inputString;
int lengthOfString=result.Length;
int changeIndex=0;
if(lengthOfString==0)
{
结果=“000”;
}
其他的
{
对于(int i=lengthOfString;i>=lengthOfString-2;i--)
{
char strotchar=(char)结果[i];
int chartPoint=(int)strochar;
如果(ChartPoint>=65&&ChartPoint让我们实现:

private static string stringCleaner(string value) {
  // let's not hardcode magic values: 3, "000" etc. but a have a constant 
  const int digits_at_least = 3;

  // special case: null or empty string
  if (string.IsNullOrEmpty(value))
    return new string('0', digits_at_least);

  int digits = 0;

  // let's count digits starting from the end
  //   && digits < digits_at_least - do not loop if we have enough digits
  //   (value[i] >= '0' && value[i] <= '9') - we want 0..9 digits only, 
  //      not unicode digits (e.g. Persian ones) - char.IsDigit
  for (int i = value.Length - 1; i >= 0 && digits < digits_at_least; --i)
    if (value[i] >= '0' && value[i] <= '9')
      digits += 1;
    else
      break;

  if (digits >= digits_at_least) // we have enough digits, return as it is
    return value;
  else
    return value.Substring(0, value.Length - digits) + 
           new string('0', digits_at_least - digits) + // inserting zeros
           value.Substring(value.Length - digits);
}
结果(无
failedReport
和所有测试通过):


从我在这个有点混乱的问题和代码中可以看出,您将这一点复杂化了很多

我会使用子字符串来提取最后3个字符,然后从后面检查该字符串是否为数字。根据遇到非数字时,使用简单的字符串串联添加一定数量的零

现在您可能对如何重写代码有了更好的了解,或许可以尝试从头开始重写代码。

char strotchar=(char)result[i];

你的问题就在这一行 您使用了从result.Length开始的i,并且results[result.Length]超出了数组的边界。您必须使用小于数组长度的i

private static string stringCleaner(string value) {
  // let's not hardcode magic values: 3, "000" etc. but a have a constant 
  const int digits_at_least = 3;

  // special case: null or empty string
  if (string.IsNullOrEmpty(value))
    return new string('0', digits_at_least);

  int digits = 0;

  // let's count digits starting from the end
  //   && digits < digits_at_least - do not loop if we have enough digits
  //   (value[i] >= '0' && value[i] <= '9') - we want 0..9 digits only, 
  //      not unicode digits (e.g. Persian ones) - char.IsDigit
  for (int i = value.Length - 1; i >= 0 && digits < digits_at_least; --i)
    if (value[i] >= '0' && value[i] <= '9')
      digits += 1;
    else
      break;

  if (digits >= digits_at_least) // we have enough digits, return as it is
    return value;
  else
    return value.Substring(0, value.Length - digits) + 
           new string('0', digits_at_least - digits) + // inserting zeros
           value.Substring(value.Length - digits);
}
  using System.Linq;

  ... 

  var testValues = new string[][] {
     new string[]{"A12","A012"},
     new string[]{"A12345","A12345"},
     new string[]{"A1B3","A1B003"},
     new string[]{null, "000"},
     new string[]{"", "000"}
  };

  // Failed tests
  var failed = testValues
    .Where(test => test[1] != stringCleaner(test[0]))
    .Select(test => 
       $"stringCleaner ({test[0]}) == {stringCleaner(test[0])} expected {test[1]}");

  string failedReport = string.Join(Environment.NewLine, failed);

  // All failed tests
  Console.WriteLine(failedReport);

  // All tests and their results
  var allTests = testValues
    .Select(test => new {
      argument = test[0],
      expected = test[1],
      actual = stringCleaner(test[0]),
    })
    .Select(test => $"{(test.expected == test.actual ? "passed" : $"failed: f({test.argument}) = {test.actual} expected {test.expected}")}");

  string allReport = string.Join(Environment.NewLine, allTests);

  Console.WriteLine(allReport); 
passed
passed
passed
passed
passed