Random uppercase letter not working [closed] - c#

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 9 years ago.
Improve this question
I want to make a random "password" generator that generates a length of different letters. You input the length and it make length random characters. I also want some random letters to be capitalized. I have a variable rndCap which to 1 or 2. The if will turn it into a capital letter if rndCap == 2, if not, it does nothing. The answer is all of the characters combined. When I execute, the numbers are all lowercase. Everything works except for it randomly capitalizing a character.
Random rnd = new Random();
string[] alphabet = new string[27];
alphabet[1] = "a";
alphabet[2] = "b";
alphabet[3] = "c";
alphabet[4] = "d";
alphabet[5] = "e";
alphabet[6] = "f";
alphabet[7] = "g";
alphabet[8] = "h";
alphabet[9] = "i";
alphabet[10] = "j";
alphabet[11] = "k";
alphabet[12] = "l";
alphabet[13] = "m";
alphabet[14] = "n";
alphabet[15] = "o";
alphabet[16] = "p";
alphabet[17] = "q";
alphabet[18] = "r";
alphabet[19] = "s";
alphabet[20] = "t";
alphabet[21] = "u";
alphabet[22] = "v";
alphabet[23] = "w";
alphabet[24] = "x";
alphabet[25] = "y";
alphabet[26] = "z";
string answer = "";
int length = Convert.ToInt32(lengthTextBox.Text);
int rndCap;
int rndLetter;
for (int i = 1; i <= length; i++)
{
rndCap = rnd.Next(1, 3);
rndLetter = rnd.Next(1, 27);
string tempMem = alphabet[rndLetter];
if (rndCap == 2)
{
tempMem.ToUpper();
}
answer = answer + tempMem;
}
passwordTextBox.Text = answer;

I'm pretty sure the IF is working :)
String.ToUpper() however doesn't change the string at hand to uppercase, but returns it as the result. You have to assign the value. What you wanted is probably this:
tempMem = tempMem.ToUpper();
Also, a rule to follow: Always bear in mind, that the
encoding, the culture and the locale can be different than that of your current one.
Even though in this case, we are only using "harmless-looking" ASCII characters, but to translate this into practice with uppercasing strings:
use the ToUpper(CultureInfo) to specify a culture
use the ToUpperInvariant() to use the "invariant culture" instead of the default one
As Jeppe noted: in the Turkish locale, i is uppercased to a character different from I - introducing unwanted consequences.

string is immutable so you need to assign it again
tempMem = tempMem.ToUpper();

You call ToUpper, but don't assign the value:
tempMem = tempMem.ToUpper()
Maybe this code is in general more elegant:
static void Main(string[] args)
{
Random cRandom = new Random(DateTime.Now.Millisecond);
string answer = "";
int length = Convert.ToInt32(6);
int rndCap;
int rndLetter;
for (int i = 1; i <= length; i++)
{
rndCap = cRandom.Next(1, 3);
rndLetter = cRandom.Next(0, 26);
char tempMem = (char)('a' + rndLetter);
string c2 = tempMem.ToString();
if (rndCap == 2)
{
c2 = tempMem.ToString().ToUpper();
}
answer = answer + c2;
}
Console.WriteLine(answer);
Console.ReadLine();
}

use this:
tempMem = tempMem.ToUpper();
as ToUpper() doesn't make uppercasing to string it is invoked on, it returns copy of this string with all letters uppercased.

ToUpper() is a method that returns an uppercase string, so you need to assign the value of tempMem to that value:
tempMem = tempMem.ToUpper();

All string manipulations returns the new string and not modifying the original since string is imutable.
Modify it like that: tempMem = tempMem.ToUpper();

I think there are simpler ways to perform what you want to achieve. Have a look at this code;
var lowerchar = "abcdefghijklmnopqrstuvwxyz";
var upperchar = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
var numbers = "0123456789";
var random = new Random();
var result = new string(
Enumerable.Repeat(lowerchar, 3)
.Select(s => s[random.Next(s.Length)])
.ToArray());
result += new string(
Enumerable.Repeat(upperchar, 3)
.Select(s => s[random.Next(s.Length)])
.ToArray());
result += new string(
Enumerable.Repeat(numbers, 2)
.Select(s => s[random.Next(s.Length)])
.ToArray());
random = new Random();
string password = new string(result.ToCharArray().OrderBy(s => random.Next().ToArray());

Related

Converting random letters within a string to Upper/Lower Case

I have a bot for my discord that I am adding a command to post one of those spongebob memes that you may have seen on twitter recently. I basically have to convert a string that the user enters, for example This is the string they would enter and it would convert it to something like this THis iS ThE sTRinG thEy WOulD EnTEr
I need to basically randomly set each character in that string to and uppercase or a lowercase.
Here is what I have so for, it prints out the original string and not the converted one.
commands.CreateCommand("spongememe").Parameter("message", ParameterType.Multiple).Do(async (e) =>
{
string message = "";
for (int i = 0; i < e.Args.Length; i++)
{
message += e.Args[i].ToString() + " ";
}
char[] array = message.ToCharArray();
for(int i = 0; i < array.Length; i++)
{
if (rnd.Next(0, 2) == 1)
Char.ToUpper(array[i]);
else
{
Char.ToLower(array[i]);
}
}
string newMessage = String.Join("", array);
await e.Channel.SendMessage(newMessage);
});
Any help on how to randomly select which characters are set to upper and lower case would be appreciated.
Here is how to randomly uppercase letters from a sentence:
var someString = "This is the string they would enter";
var randomizer = new Random();
var final =
someString.Select(x => randomizer.Next() % 2 == 0 ?
(char.IsUpper(x) ? x.ToString().ToLower().First() : x.ToString().ToUpper().First()) : x);
var randomUpperLower = new string(final.ToArray());
Console.WriteLine(randomUpperLower);
<== Try Me ==>
Char.ToUpper(char c); and Char.ToLower(char c); takes the char argument, transforms it either to uppercase or lowercase, and returns the transformed result. It doesn't change the char itself (see "Value and Reference Types" https://msdn.microsoft.com/en-us/library/4d43ts61(v=vs.90).aspx).
You need to modify it to something like this: array[i] = Char.ToUpper(array[i]);

How can I capitalize every third letter of a string in C#?

How can I capitalize every third letter of a string in C#?
I loop through the whole string with a for loop, but I can't think of the sequence right now.
I suspect you just want something like this:
// String is immutable; copy to a char[] so we can modify that in-place
char[] chars = input.ToCharArray();
for (int i = 0; i < chars.Length; i += 3)
{
chars[i] = char.ToUpper(chars[i]);
}
// Now construct a new String from the modified character array
string output = new string(chars);
That assumes you want to start capitalizing from the first letter, so "abcdefghij" would become "AbcDefGhiJ". If you want to start capitalizing elsewhere, just change the initial value of i.
var s = "Lorem ipsum";
var foo = new string(s
.Select((c, i) => (i + 1) % 3 == 0 ? Char.ToUpper(c) : c)
.ToArray());
You are already looping through the characters inside a string? Then add a counter, increment it on each iteration, and if it is 3, then use .ToUpper(currentCharacter) to make it upper case. Then reset your counter.
You could just use a regular expression.
If the answer is every third char then you want
var input = "sdkgjslgjsklvaswlet";
var regex = new Regex("(..)(.)");
var replacement = regex.Replace(input, delegate(Match m)
{
return m.Groups[1].Value + m.Groups[2].Value.ToUpper();
});
If you want every third character, but starting with the first you want:
var input = "sdkgjslgjsklvaswlet";
var regex = new Regex("(.)(..)");
var replacement = regex.Replace(input, delegate(Match m)
{
return m.Groups[1].Value.ToUpper() + m.Groups[2].Value;
});
If you want a loop, you can convert to a character array first, so you can alter the values.
For every third character:
var x = input.ToCharArray();
for (var i = 2; i <x.Length; i+=3) {
x[i] = char.ToUpper(x[i]);
}
var replacement = new string(x);
For every third character from the beginning:
var x = input.ToCharArray();
for (var i = 0; i <x.Length; i+=3) {
x[i] = char.ToUpper(x[i]);
}
var replacement = new string(x);

Efficient method for converting text to phone keypad

I have the following code for converting a string containing alphanumeric characters to a string of numbers that can be entered into a phone using the phone's keypad:
string text = "sometext containing spaces and numbers 12345";
Dictionary<char, char> alphabetMapping = new Dictionary<char, char>();
alphabetMapping['a'] = '2';
alphabetMapping['b'] = '2';
alphabetMapping['c'] = '2';
alphabetMapping['d'] = '3';
alphabetMapping['e'] = '3';
alphabetMapping['f'] = '3';
alphabetMapping['g'] = '4';
alphabetMapping['h'] = '4';
alphabetMapping['i'] = '4';
alphabetMapping['j'] = '5';
alphabetMapping['k'] = '5';
alphabetMapping['l'] = '5';
alphabetMapping['m'] = '6';
alphabetMapping['n'] = '6';
alphabetMapping['o'] = '6';
alphabetMapping['p'] = '7';
alphabetMapping['q'] = '7';
alphabetMapping['r'] = '7';
alphabetMapping['s'] = '7';
alphabetMapping['t'] = '8';
alphabetMapping['u'] = '8';
alphabetMapping['v'] = '8';
alphabetMapping['w'] = '9';
alphabetMapping['x'] = '9';
alphabetMapping['y'] = '9';
alphabetMapping['z'] = '9';
alphabetMapping['1'] = '1';
alphabetMapping['2'] = '2';
alphabetMapping['3'] = '3';
alphabetMapping['4'] = '4';
alphabetMapping['5'] = '5';
alphabetMapping['6'] = '6';
alphabetMapping['7'] = '7';
alphabetMapping['8'] = '8';
alphabetMapping['9'] = '9';
alphabetMapping['0'] = '0';
alphabetMapping['.'] = '0';
alphabetMapping[','] = '0';
alphabetMapping['#'] = '0';
alphabetMapping['*'] = '*';
alphabetMapping['#'] = '#';
alphabetMapping[' '] = '0'; // not sure if this underscore or space
StringBuilder sb = new StringBuilder();
foreach (var c in text)
{
sb.Append(alphabetMapping[c]);
}
Console.WriteLine(sb.ToString());
The output:
76638398026682464640772237026306862377012345
Not that this has much practical use, but some automated phone systems ask for passwords that may contain letters so I wrote this code for helping with that.
Is there a more efficient method for this or am I on the right track?
An elegant way to convert phone letters to their respective numbers is to use Regular Expressions. Here is the function that I use. It may need to be tweaked to fit your scenario.
internal static string ConvertPhoneTexttoNumber(string PhoneNumber)
{
PhoneNumber = Regex.Replace(PhoneNumber, #"[abcABC]", "2");
PhoneNumber = Regex.Replace(PhoneNumber, #"[defDEF]", "3");
PhoneNumber = Regex.Replace(PhoneNumber, #"[ghiGHI]", "4");
PhoneNumber = Regex.Replace(PhoneNumber, #"[jklJKL]", "5");
PhoneNumber = Regex.Replace(PhoneNumber, #"[mnoMNO]", "6");
PhoneNumber = Regex.Replace(PhoneNumber, #"[pgrsPGRS]", "7");
PhoneNumber = Regex.Replace(PhoneNumber, #"[tuvTUV]", "8");
PhoneNumber = Regex.Replace(PhoneNumber, #"[wxyzWXYZ]", "9");
//remove all non alphanumeric characters
PhoneNumber = Regex.Replace(PhoneNumber, #"[\W]", "");
return PhoneNumber;
}
This solution will work for any number of characters in a string. If you want to keep the parentheses and dashes remove this line:
PhoneNumber = Regex.Replace(PhoneNumber, #"[\W]", "");
Note: If you don't know how to use Regular Expressions, here is a great tutorial:
https://regexone.com/lesson/introduction_abcs
You could use fewer lines of code if you grouped all of your items together.
var allValues = new List<KeyValuePair<string,char>>()
allValues.Add(new KeyValuePair("abc2","2"));
allValues.Add(new KeyValuePair("def3","3"));
etc, etc
StringBuilder sb = new StringBuilder();
foreach (var c in text)
{
var matched = allValues.FirstOrDefault(kvp=> kvp.Key.Contains(c));
if(matched != null)
{
sb.Append(matched.Value);
}
else
{
sb.Append(" ");
}
}
Console.WriteLine(sb.ToString());
It's probably not computationally more efficient, but it's less for a human to read.
Considering the size of the dataset (alphanumeric characters and letters) and the intended application, this seems like the most logical and seemingly optimal way to do it. If you wanted to improve the performance you could use a HashSet, but I'm not sure you would see any measurable gain from that with this dataset.

How can I parse a string into different strings in C#?

I just started work on a C# application. I need to break down a string into different parts. Is there an easy way to do this using C# patterns? I think I can do it with substrings but it might get messy and I want to do something that's easy to understand. Here's an example of the input:
AB-CDE-GHI-123-45-67-7777
variable1 = "AB-CDE-GHI"
variable2 = "123"
variable3 = "45"
variable4 = "67"
variable5 = "67-7777"
AB-CDE-GHIJKLM-123-45-67-7777
variable1 = "AB-CDE-GHIJKLM"
variable2 = "123"
variable3 = "45"
variable4 = "67"
variable5 = "67-7777"
AB-123-45-67-7777
variable1 = "AB"
variable2 = "123"
variable3 = "45"
variable4 = "67"
variable5 = "67-7777"
The first part of the string up until "123-45-67-7777" can be any length. Lucky for me the last part 123-45-67-7777 is always the same length and contains numbers that are zero padded.
I hope someone can come up with some suggestions for an easy method that uses regular expressions or something.
Input lines look like this:
aa-123-45-67-7777
HJHJH-123-45-67-7777
H-H-H--123-45-67-7777
222-123-45-67-7777
You do not need RegEx for parsing this kind of input.
You can use string.Split, in particular if the input is highly structured.
If you first split by - you will get a string[] with each part in a different index of the array.
The length property of the array will tell you how many parts you got and you can use that to reconstruct the parts you need.
You can rejoin any of the bit you need back.
string[] parts = "AB-CDE-GHI-123-45-67-7777".split('-');
// joining together the first 3 items:
string letters = string.Format("{0}-{1}-{2}", parts[0], parts[1], parts[2]);
// letters = "AB-CDE-GHI"
If the number of sections is variable (apart from the last 4), you can use the length in a loop to rebuild the wanted parts:
StringBuilder sb = new StringBuilder();
for(int i = 0; i < parts.Length - 4; i++)
{
sb.FormatAppend("{0}-", parts[i]);
}
sb.Length = sb.Length - 1; // remove trailing -
If the last part is always a known length (14 characters) you could just do something like this:
var firstPart = inputLine.Substring(inputLine.Length - 14);
var secondPart = inputLine.Substring(0, inputLine.Length - 15); // 15 to exclude the last -
Then you can just do your string splitting and job done :)
Although it is possible to use here String.Split, a better solution, in my opinion, would be to tokenize the input and then parse it.
You can use tools such as ANTLR for this purpose.
string[] str = "AB-CDE-GHI-123-45-67-7777".Split('-')
int a = str.Length;
variable1="";
for(int i=0;i=<a-5;i++)
{
variable1=str[i]+"-"+variable1;
}
// last - remove
variable1 = variable1.Remove(variable1.Length-1,1);
variable2 = str[a-4]
variable3 = str[a-3]
variable4 = str[a-2]
variable5 = str[a-2]+"-"str[a-1];
like Oded say you can use string.Split
I edit my answer like you want
string[] tab = textBox1.Text.Split('-');
int length = tab.Length;
string var1 = string.Empty;
for(int i=0; i <= length-5 ; i++)
{
var1 = var1 + tab[i] + '-';
}
var1 = var1.Remove(var1.Length-1,1);
string var2 = tab[length-4];
string var3 = tab[length-3];
string var4 = tab[length-2];
string var5 = tab[length-2] + '-' + tab[length-1];
it's the same with the answer of #Govind KamalaPrakash Malviya just you have make var1 + tab[i]

Format string with dashes

I have a compressed string value I'm extracting from an import file. I need to format this into a parcel number, which is formatted as follows: ##-##-##-###-###. So therefore, the string "410151000640" should become "41-01-51-000-640". I can do this with the following code:
String.Format("{0:##-##-##-###-###}", Convert.ToInt64("410151000640"));
However, The string may not be all numbers; it could have a letter or two in there, and thus the conversion to the int will fail. Is there a way to do this on a string so every character, regardless of if it is a number or letter, will fit into the format correctly?
Regex.Replace("410151000640", #"^(.{2})(.{2})(.{2})(.{3})(.{3})$", "$1-$2-$3-$4-$5");
Or the slightly shorter version
Regex.Replace("410151000640", #"^(..)(..)(..)(...)(...)$", "$1-$2-$3-$4-$5");
I would approach this by having your own formatting method, as long as you know that the "Parcel Number" always conforms to a specific rule.
public static string FormatParcelNumber(string input)
{
if(input.length != 12)
throw new FormatException("Invalid parcel number. Must be 12 characters");
return String.Format("{0}-{1}-{2}-{3}-{4}",
input.Substring(0,2),
input.Substring(2,2),
input.Substring(4,2),
input.Substring(6,3),
input.Substring(9,3));
}
This should work in your case:
string value = "410151000640";
for( int i = 2; i < value.Length; i+=3){
value = value.Insert( i, "-");
}
Now value contains the string with dashes inserted.
EDIT
I just now saw that you didn't have dashes between every second number all the way, to this will require a small tweak (and makes it a bit more clumsy also I'm afraid)
string value = "410151000640";
for( int i = 2; i < value.Length-1; i+=3){
if( value.Count( c => c == '-') >= 3) i++;
value = value.Insert( i, "-");
}
If its part of UI you can use MaskedTextProvider in System.ComponentModel
MaskedTextProvider prov = new MaskedTextProvider("aa-aa-aa-aaa-aaa");
prov.Set("41x151000a40");
string result = prov.ToDisplayString();
Here is a simple extension method with some utility:
public static string WithMask(this string s, string mask)
{
var slen = Math.Min(s.Length, mask.Length);
var charArray = new char[mask.Length];
var sPos = s.Length - 1;
for (var i = mask.Length - 1; i >= 0 && sPos >= 0;)
if (mask[i] == '#') charArray[i--] = s[sPos--];
else
charArray[i] = mask[i--];
return new string(charArray);
}
Use it as follows:
var s = "276000017812008";
var mask = "###-##-##-##-###-###";
var dashedS = s.WithMask(mask);
You can use it with any string and any character other than # in the mask will be inserted. The mask will work from right to left. You can tweak it to go the other way if you want.
Have fun.
If i understodd you correctly youre looking for a function that removes all letters from a string, aren't you?
I have created this on the fly, maybe you can convert it into c# if it's what you're looking for:
Dim str As String = "410151000vb640"
str = String.Format("{0:##-##-##-###-###}", Convert.ToInt64(MakeNumber(str)))
Public Function MakeNumber(ByVal stringInt As String) As String
Dim sb As New System.Text.StringBuilder
For i As Int32 = 0 To stringInt.Length - 1
If Char.IsDigit(stringInt(i)) Then
sb.Append(stringInt(i))
End If
Next
Return sb.ToString
End Function

Categories

Resources