Reputation: 55
(C#)My code seems to be fine but whenever I put 0 as the second parameter it will display "Enemy50" when I want enemy 57 to change to enemy 00. I think theres a problem with the third if statement but not sure for to fix it.
Main
string enemy57 = "enemy57";
Console.WriteLine("The old image name is: " + enemy57);
Console.WriteLine("New image name: " + BuildingBlock.NextImageName(enemy57, 0));
Console.ReadLine();
class BuildingBlock
{
public static string ReplaceOnce(string word, string characters, int position)
{
word = word.Remove(position, characters.Length);
word = word.Insert(position, characters);
return word;
}
public static string GetLastName(string name)
{
string result = "";
int posn = name.LastIndexOf(' ');
if (posn >= 0) result = name.Substring(posn + 1);
return result;
}
public static string NextImageName(string filename, int newNumber)
{
if (newNumber > 9)
{
return ReplaceOnce(filename, newNumber.ToString(), (filename.Length - 2));
}
if (newNumber < 10)
{
return ReplaceOnce(filename, newNumber.ToString(), (filename.Length - 1));
}
if (newNumber == 0)
{
return ReplaceOnce(filename, newNumber.ToString(), (filename.Length - 2));
}
return filename;
}
Upvotes: 1
Views: 170
Reputation: 216313
Try to replace your last call to ReplaceOnce with
return ReplaceOnce(filename, newNumber.ToString("D2"), (filename.Length - 2));
The problem is because you pass the integer 0 that is converted to the string "0" which has a length of 1 char. So the ReplaceOnce method replace only the last char leaving the 5 in place.
Using the ToString composite formatting rule D2 ensure that whatever number you pass to the method will be formatted with at least two chars.
Said that, seeing that you test for newNumber == 0 you could also write
return ReplaceOnce(filename, "00", (filename.Length - 2));
Also, the test for zero should be executed before the test for < 10 otherwise you call the method with wrong parameters.
public static string NextImageName(string filename, int newNumber)
{
if (newNumber == 0)
{
return ReplaceOnce(filename, "00", (filename.Length - 2));
}
if (newNumber > 9)
{
return ReplaceOnce(filename, newNumber.ToString(), (filename.Length - 2));
}
if (newNumber < 10)
{
return ReplaceOnce(filename, newNumber.ToString(), (filename.Length - 1));
}
// Unreachable code ???
// return filename;
}
If you are sure that twh ending characters are always two digits and you want to replace the current digits with two other digits also for one digits only newNumber
you could write
public static string NextImageName(string filename, int newNumber)
{
// ToString("D2") forces the 1-9 range to be passed as 0X no need to test
return ReplaceOnce(filename, newNumber.ToString("D2"), (filename.Length - 2));
}
removing all the now unnecessary tests on the digits length
Upvotes: 1
Reputation: 4532
the problem with your code is the last if statement which checks for 0 but before you have a check for < 10 which if newnumber is 0 will enter.So its just switch that if above the other 2 or between them like this:
public static string NextImageName(string filename, int newNumber)
{
if (newNumber == 0)
{
return ReplaceOnce(filename, newNumber.ToString(), (filename.Length - 2));
}
if (newNumber > 9)
{
return ReplaceOnce(filename, newNumber.ToString(), (filename.Length - 2));
}
if (newNumber < 10)
{
return ReplaceOnce(filename, newNumber.ToString(), (filename.Length - 1));
}
return filename;
}
Or if you want as an example you can also eliminate the ReplaceOnce method and do it all like this:
public static string NextImageName(string filename, int newNumber)
{
if (newNumber == 0)
{
return Regex.Replace(filename, @"[\d+]", newNumber.ToString());
}
if (newNumber > 9)
{
return Regex.Replace(filename, @"(\d+)(?!.*\d)", newNumber.ToString());
}
if (newNumber < 10)
{
return Regex.Replace(filename, @"(\d)(?!.*\d)", newNumber.ToString());
}
return filename;
}
Upvotes: 1
Reputation: 391486
Here's an example that will likely do what you want.
It will:
Meaning that:
Enemy01, replace with 5, will be Enemy05
Enemy57, replace with 5, will be Enemy05
Enemy1, replace with 57, will be Enemy57
Here's a LINQPad program that demonstrates:
void Main()
{
NextImageName("Enemy01", 5).Dump();
NextImageName("Enemy57", 5).Dump();
NextImageName("Enemy5", 57).Dump();
}
public static string NextImageName(string filename, int newNumber)
{
var re = new Regex(@"\d+$");
return re.Replace(filename, match =>
{
return newNumber.ToString().PadLeft(match.Length, '0');
});
}
Output:
Enemy05
Enemy05
Enemy57
The regular expression
\d+$
means this:
+- one or more times
v
\d+$
^^ ^
| |
| +-- followed by the end of the string
|
digits (0-9)
In other words:
Upvotes: 2