PadLeft and PadRight using variables given in by user - c#

I have a small problem using PadLeft and PadRight.
So I have in my code that the user can input the character they want to use for padding and how many characters they wanna put in. Like this:
String StartString;
int AmountOfCharacters;
Char PadCharacter;
StartString = TextBoxString.Text(Lawnmower)
AmountOfCharacters = Convert.ToInt32(TextBoxAmountofCharacters.Text) (Lets Say 5)
PadCharacter = Convert.ToChar(TextBoxPadCharacter.Text)(Lets use *)
So then later i have put.
Padding = String.PadLeft(AmountOfCharacters,PadCharacter)
Now the problem I have when I run the code as I have it above it doesn't do anything.
It just gives me as text lawnmower without any **** attatched.
Do I have to change something in my code to make it work or am I using the wrong variables for this?
Because when I use the PadCharacter as a String to I get a error message
Cannot implicitly convert String to char.

You misunderstand how PadLeft() works. The length you specify as a parameter (in your case AmountOfCharacters) does not specify how many characters you want added but how many characters the string should have at the end (at least).
So when you specify the string "Lawnmower" and AmountOfCharacters = 5, nothing will happen because the word Lawnmower is already more than 5 characters long.

If StartString charecter count is less then AmountOfCharacters you can see stars infront of StartString. The number of stars will be
[AmountOfCharacters] - [StartString Character Count]

String is a sequence of characters, but not itself a character - that's why Convert.ToChar fails with an exception. Try TextBoxPadCharacter[0] to get the first character of user input. You will also need to verify that the input is non-empty.

Related

Decimal.TryParse Fails to parse integer value

What am I missing:
decVal = Decimal.Parse(myAr[0]);
Or
Decimal.TryParse(myAr[0], out decVal);
Fails !
Input string was not in correct foramt.
myAr[0] is "678016".
Tried to add NumberStyle.Any and CultureInfo.InvarialtCulture but got the same results.
More info on the string:
it is concatenated with some letters in hebrew and a "\u200e" space between them. and then I use split(' ') to get the numbers back.
This is probably the source of this error, but when I check the myAr[0] in the watch it is pure string....
Guys I've found the answer, I'll rewrite the question for future generation.
The Original string was a concatenation of letters and numbers separated with a special sequence to preserve the order in a rtl situation: "\u200E".
The number where extracted later using string.split(' ') which seems to work OK (in the watch) be it caused the problem.
once I used string.split("\u200e").ToCharArray() I got the same results, but now the decimal.Parse is working.
It looks like the special char was still inside the string, invisible to the watch.
This is weird, on my machine (.NET 4) even this works:
Decimal.TryParse("asdf123&*", out someDecimal);
By works I mean that TryParse returns false, no exception is thrown.
Parse method may throw an exception - maybe you have some whitespace or string literally contains " (quotes)?

custom string format puzzler

We have a requirement to display bank routing/account data that is masked with asterisks, except for the last 4 numbers. It seemed simple enough until I found this in unit testing:
string.Format("{0:****1234}",61101234)
is properly displayed as: "****1234"
but
string.Format("{0:****0052}",16000052)
is incorrectly displayed (due to the zeros??): "****1600005252""
If you use the following in C# it works correctly, but I am unable to use this because DevExpress automatically wraps it with "{0: ... }" when you set the displayformat without the curly brackets:
string.Format("****0052",16000052)
Can anyone think of a way to get this format to work properly inside curly brackets (with the full 8 digit number passed in)?
UPDATE: The string.format above is only a way of testing the problem I am trying to solve. It is not the finished code. I have to pass to DevExpress a string format inside braces in order for the routing number to be formatted correctly.
It's a shame that you haven't included the code which is building the format string. It's very odd to have the format string depend on the data in the way that it looks like you have.
I would not try to do this in a format string; instead, I'd write a method to convert the credit card number into an "obscured" string form, quite possibly just using Substring and string concatenation. For example:
public static string ObscureFirstFourCharacters(string input)
{
// TODO: Argument validation
return "****" + input.Substring(4);
}
(It's not clear what the data type of your credit card number is. If it's a numeric type and you need to convert it to a string first, you need to be careful to end up with a fixed-size string, left-padded with zeroes.)
I think you are looking for something like this:
string.Format("{0:****0000}", 16000052);
But I have not seen that with the * inline like that. Without knowing better I probably would have done:
string.Format("{0}{1}", "****", str.Substring(str.Length-4, 4);
Or even dropping the format call if I knew the length.
These approaches are worthwhile to look through: Mask out part first 12 characters of string with *?
As you are alluding to in the comments, this should also work:
string.Format("{0:****####}", 16000052);
The difference is using the 0's will display a zero if no digit is present, # will not. Should be moot in your situation.
If for some reason you want to print the literal zeros, use this:
string.Format("{0:****\0\052}", 16000052);
But note that this is not doing anything with your input at all.

How to in C# keep a set number of letters for a string in console writeline

Ok so basically I want something like
Console.WriteLine(
"{0}: {1}/{2}hp {3}/{4}mp {5}",
character.Identifier,
character.CurrentHealth,
character.MaxHealth,
character.CurrentMagic,
character.MaxMagic,
character.Fatigue
);
and then have the character.Identifier (which is basically a name) have a set number of letters which it will replace with spaces if needed so that in might print
Josh: 20/20hp 20/20mp 3
or
J: 20/20hp 20/20mp 3
but the HP and then mp and everything else is always in line.
I am aware that its probably one of the {0:} but i couldn't figure out one that works
The second argument in the {0} notation can give you a fixed width field, so if you wanted the identifier (name) to always be 10 characters long and be left justified, you would use {0,-10}
MSDN is a good resource for this kind of question too, if you read the documentation for String.Format it has an example of a fixed width table that might be similar to what you want.
Also, as Hogan's answer correctly points out, you would have to append the : to the string outside of the format string if you want it right next to the name.
You can right pad a string with spaces by using:
character.Identifier.PadRight(10);
This should give you the format you are after.
I believe this will do what you want:
const int colWidth = 10;
Console.WriteLine("{0,-"+colWidth.ToString()+"}{1,-"+colWidth.ToString()+"}{2,-"+colWidth.ToString()+"}{3}",
(character.Identifier+":").PadRight(colWidth+1).Remove(0,colWidth),
(character.CurrentHealth+"/"+character.MaxHealth+"hp").PadRight(colWidth+1).Remove(0,colWidth),
(character.CurrentMagic+"/"+character.MaxMagic+"mp").PadRight(colWidth+1).Remove(0,colWidth),
(character.Fatigue,colWidth));
This will add spaces to the end of string and then truncate the result.
See the docs for String.Format
NOTES
I append the : to the name outside of the format string and I "merge" the hp and mp sections and then put them in a column.

Replacing part of text in richtextbox

I need to compare a value in a string to what user typed in a richtextbox.
For example: if a richtextbox holds string rtbText = "aaaka" and I compare this to another variable string comparable = "ka"(I want it to compare backwards). I want the last 2 letters from rtbText (comparable has only 2 letters) to be replaced with something that was predetermined(doesn't really matter what).
So rtbText should look like this:
rtbText = "aaa(something)"
This doesn't really have to be compared it can just count letters in comparable and based on that it can remove 2 letters from rtbText and replace them with something else.
UPDATE:
Here is what I have:
int coLen = comparable.Length;
comparable = null;
TextPointer caretBack = rtb.CaretPosition.GetPositionAtOffset(coLen, LogicalDirection.Backward);
TextRange rtbText = new TextRange(rtb.CaretPosition, caretBack);
string text = rtbText.Text;
rtbText returns an empty string or I get an error for everything longer than 3 characters. What am I doing wrong?
Let me elaborate it a little bit further. I have a listbox that holds replacements for values that user types in rtb. The values(replacements) are coming from there, meaning that I don't really need to go through the whole text to check values. I just need to check the values right before caret. I am comparing these values to what I have stored in another variable (comparable).
Please let me know if you don't understand something.
I did my best to explain what needs to be done.
Thank you
You could use Regex.Replace.
// this replaces all occurances of "ka" with "Replacement"
Regex replace = new Regex("ka");
string result = replace.Replace("aaaka","Replacemenet");
gumenimeda, I had similar problems few weeks ago. I found my self doing the following (I asume you will have more than one occurance in the RichTextBox that you will need to change), note that I did it for Windows Forms where I have access directly to the Rtf text of the control, not quite sure if it will work well in your scenario:
I find all the occurancies of the string (using IndexOf for example) and store them in a List for example.
Sort the list in descending order (max index goes first, the one before him second, etc)
Start replacing the occurancies directly in the RichTextBox, by removing the characters I don't need and appending the characters I need.
The sorting in step 2 is necessary as we always want to start from the last occurance going up to the first. Starting from the first occurance or any other and going down will have an unpleasant surprise - if the length of the chunk you want to remove and the length of the chunk you want to append are different in length, the string will be modified and all other occurancies will be invalid (for example if the second occurance was in at position 12 and your new string is 2 characters longer than the original, it will become 14th). This is not an issue if we go from the last to the first occurance as the change in string will not affect the next occurance in the list).
Ofcourse I can not be sure that this is the fastest way that can be used to achieve the desired result. It's just what I came up with and what worked for me.
Good luck!

String Format Does Not Works For string

I have a serial number which is String type.
Like This;
String.Format("{0:####-####-####-####}", "1234567891234567" );
I need to see Like This, 1234-5678-9123-4567;
Bu this Code does not work?
Can you help me?
That syntax takes an int, try this:
String.Format("{0:####-####-####-####}", 1234567891234567);
Edit: If you want to use this syntax on a string try this:
String.Format("{0:####-####-####-####}", Convert.ToInt64("1234567891234567"))
For ####-####-####-####, you will need a number. But you're feeding it a string.
It would be more practical to pad the string with additional zero's on the left so it becomes exactly 16 characters. Then insert the dash in three locations inside the string. Converting it to an Int64 will also work but if these strings become bigger or start to contain non-numerics, then you will have a problem.
string Key = "123456789012345";
string FormattedKey = Key.PadLeft(16, '0').Insert(12, "-").Insert(8, "-").Insert(4, "-");
That should be an alternative to formatting. It makes the key exactly 16 characters, then inserts three dashes from right to left. (Easier to keep track of indices.)
There are probably plenty of other alternatives but this one works just fine.

Categories