user2883997
user2883997

Reputation: 241

How do I join string in an array into one string and display it in the console?

I am trying to learn C#. I already know Python. I wanted to replicate a simple password generator program I wrote in Python with C#. My problem is I don't know how to join the characters together into one string so I can display it. When I try to display it I just get blank spaces where the characters from the password should be.

In Python I can do this

password = []#will have random items appended by generator code
s = ''.join(password)#makes one string
print(s)#prints
namespace learning
{
    public static class PasswordGenerator
    {
        private static string Letters = "abcdefghijklmnopqrstuvwxyz";
        private static string Numbers = "1234567890";
        private static string Symbols = "!@#$%^&*()";

        public static string Generate()
        {
            string[] letters = new string[10];
            string[] choice = { "letter", "number", "symbol" };
            string[] UL = { "uper", "lower" };
            string get;
            char c;
            for (int i = 0; i <= 9; i++)
            {
                get = Rand.RandString(choice);
                if (get == "letter")
                {
                    c = Rand.RandChar(Letters);
                    get = Rand.RandString(UL);
                    if (get == "uper")
                    {
                        c = char.ToUpper(c);
                        letters.Append(c.ToString());
                    }
                    else
                    {
                        letters.Append(c.ToString());
                    }
                }
                if (get == "number")
                {
                    c = Rand.RandChar(Numbers);
                    letters.Append(c.ToString());
                }
                if (get == "symbol")
                {
                    c = Rand.RandChar(Symbols);
                    letters.Append(c.ToString());
                }
            }
            return String.Join(",", letters);
        }
    }
    public class Rand
    {
        private static Random Generator = new Random();
        public static Char RandChar(string items) //Choose a random char from string
        {
            int myIndex = Generator.Next(items.Length);
            char l = items[myIndex];
            return l;
        }
        public static string RandString(string[] items)//Choose a random string from a list
        {
            int myIndex = Generator.Next(items.Length);
            string s = items[myIndex];
            return s;
        }
    }
}

When I run the code I call Console.WriteLine(PasswordGenerator.Generate()) but It will not print my password. It will only print some commas and have blank spaces where the characters from the password should be. I need it to display my password. What am I doing wrong? How can I get it to display my password?

Upvotes: 0

Views: 84

Answers (3)

TheGeneral
TheGeneral

Reputation: 81513

To add to the other answers, you also have an issue with your ifs, they should be if then else or a switch if you want to keep your length correct

Small refactor

Uses an iterator method and a switch

public static IEnumerable<char> Generate(int size, string[] choice, string[] ul)
{
   for (var i = 0; i < size; i++)
   {
      switch (Rand.RandString(choice))
      {
         case "letter":
               if (Rand.RandString(ul) == "uper")
                  yield return char.ToUpper(Rand.RandChar(Letters));
               else
                  yield return Rand.RandChar(Letters);
               break;               
         case "number":
            yield return Rand.RandChar(Numbers);
            break;
         case "symbol":
            yield return Rand.RandChar(Symbols);
            break;
      }
   }
}

Usage

string[] choice = { "letter", "number", "symbol" };
string[] UL = { "uper", "lower" };
Console.WriteLine(string.Concat(Generate(10, choice, UL)));

Demo here

https://dotnetfiddle.net/qSHimm

Or another way

public class Rand
{
   private static Random Generator = new Random();
   public static T Get<T>(T[] items) //Choose a random char from string
      =>  items[Generator.Next(items.Length)];

}
private static string Letters = "abcdefghijklmnopqrstuvwxyz";
private static string Numbers = "1234567890";
private static string Symbols = "!@#$%^&*()";

public enum Options
{
   Upper,Lower, Numbers, Symbols
}

public static IEnumerable<char> Generate(int size, params Options[] options)
{
   for (var i = 0; i < size; i++)
   {
      switch (Rand.Get(options))
      {
         case Options.Upper: yield return char.ToUpper(Rand.Get(Letters.ToCharArray())); break;
         case Options.Lower: yield return Rand.Get(Letters.ToCharArray()); break;
         case Options.Numbers: yield return Rand.Get(Numbers.ToCharArray()); break;
         case Options.Symbols: yield return Rand.Get(Symbols.ToCharArray());break;
      }
   }
}

Usage

Console.WriteLine(string.Concat(Generate(10, Options.Upper,Options.Numbers)));

Output

R0P76UYO1D

Or another way

public static string Generate(int size, params Options[] options)
   => string.Concat(Enumerable.Repeat(0,size).Select(x => GetChar(options)));

private static char GetChar(params Options[] options)
{
   switch (Rand.Get(options))
   {
      case Options.Upper:  return char.ToUpper(Rand.Get(Letters.ToCharArray())); ;
      case Options.Lower: return Rand.Get(Letters.ToCharArray()); 
      case Options.Numbers:  return Rand.Get(Numbers.ToCharArray()); 
      case Options.Symbols:  return Rand.Get(Symbols.ToCharArray());
      default: throw new ArgumentOutOfRangeException();
   }
}

Usage

Console.WriteLine(Generate(10, Options.Upper,Options.Numbers));

Upvotes: 1

Anu Viswan
Anu Viswan

Reputation: 18155

When you are attempting letters.Append, you are attempting to append an array, which is not possible since it is fixed length.You could use List<String>, but in this particular case, you could instead make use of a specialized .Net class, called StringBuilder.

Since string is immutable, in situations where you need to perform repeated modifications to a string, such as appending values to it, the overhead associated with creating a new String object can be costly. This is where StringBuilder comes into rescue.

var letters = new StringBuilder();

Now, you can append the characters without the ToString() conversion.

letters.Append(c)

Finally, to return the string from StringBuilder, you can use the ToString method.

return letters.ToString();

Upvotes: 2

GregN
GregN

Reputation: 142

This looks overly complicated for generating a random password. You could use the code below using an optional parameter (if they pass nothing to the function it generates it with a length of 15).

private static string CreateRandomPassword(int length = 15)
{
    string validChars = "ABCDEFGHJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789!@#$%^&*?_-";
    Random random = new Random();

    // Select one random character at a time from the string  
    // and create an array of chars  
    char[] chars = new char[length];

    for (int i = 0; i < length; i++)
    {
        chars[i] = validChars[random.Next(0, validChars.Length)];
    }
    return new string(chars);
}

Found this quick solution just googling this url: https://www.c-sharpcorner.com/article/how-to-generate-a-random-password-in-c-sharp-and-net-core/

Upvotes: 0

Related Questions