Cypher Program on C# with a function - c#

Why doesn't my code work?? I am writing a cypher program in C# and would like to know why this isn't working. The error that I keep on getting is 'not all code paths return a value'
this is my code:

If passed string will be empty then the return will never be hit, so the method will not return anything.
public static string cypher(string word)
{
// If word is null, we just return null.
if(string.IsNullOrEmpty(word))
return null;
// Process string. This will return after first char...
foreach (char d in word)
{
char charCypher = System.Convert.ToChar((int)d+2);
return Convert.ToString(charCypher);
}
}
Not exactly what the question is about, but you iterate through each char of a word, but you return after first char. You probably want to cypher every char and return cyphered word. In this case you need to modify your code:
public static string cypher(string word)
{
// If word is null, we just return null.
if(string.IsNullOrEmpty(word))
return null;
StringBuilder builder = new StringBuilder();
foreach (char d in word)
{
char charCypher = System.Convert.ToChar((int)d+2);
builder.Append(Convert.ToString(charCypher));
}
return builder.ToString();
}

The foreach loop in cypher can contain an empty string, so the loop won't be executed if that's the case. Therefore it won't hit your return statement.
A workaround for this problem could be adding return String.Empty before the last closing brace or your method.

It seems, that you want to implement Caesar cipher:
using System.Linq;
...
public static string cypher(string word) {
//DONE: do not forget to validate public method's arguments
if (string.IsNullOrEmpty(word))
return word;
//TODO: you may want to make some amendments
// 1. Filter out which characters to encode (e.g. skip new lines)
// 2. Add modulo operator (e.g. to encode letters as letters)
return string.Concat(word.Select(d => (char)(d + 2)));
}
Please, do not forget to cast integer back to char when concatenating the string

Related

Simple Password Tester C#

I'm tinkering with a very basic password tester. I'm trying to compare the input string with a given string of acceptable characters.
public static bool hasRequiredChar(string input)
{
input = "input";
string requiredChar = "abcde";
foreach (var item in requiredChar)
{
if (input.Contains(item)) return true;
}
return false;
}
If I only use System, I get the error message: "Argument 1: cannot convert from 'char' to 'string'". This refers to the string.Contains() method. Any ideas?
I know there are 1000 ways to write this differently but I don't want to use Regex, Linq or anything other than System.
You're passing to string.Contains a char, when in .NET Framework it instead expects a string. To pass in the argument, simply cast it to a string first.
foreach (var item in requiredChar)
{
if (input.Contains(item.ToString()) return true;
}
There are some other problems with your approach if you're trying to check if the string contains all required characters, but that's aside from your error.

Console.Writeline escape character from variable

I've got an extension method that converts me ulong into a string value with some kind of encryption. I want to output them as they are just by using Console.WriteLine, in most scenarios it works but there is a problem with values with escapes characters. For example "(V\\\|RN" outputs just "(V\|RN".
var result = id.IdToCode();
Console.WriteLine(result);
or
Console.WriteLine(id.IdToCode());
The method IdToCode returns stringBuilder.ToString()
I've tried many combinations with putting somewhere # to return the string as it is but without any result. Maybe I should override the default behavior of Console.WriteLine or the stringBuilder.ToString() is the problem here?
Here is a screen of what I mean.
And below the code of IdToCode method:
public static string IdToCode(this ulong value)
{
const string charArray = #"1234890qwertyuiopbnmQWERTYUasdfghjklzxcvIOPASDFGHJKLZXCVBNM!+={}[]|\<>?##567$%^&*()-_";
StringBuilder stringBuilder = new StringBuilder();
ulong num = value;
while (num != 0UL)
{
ulong index = num % (ulong)charArray.Length;
num /= (ulong)charArray.Length;
stringBuilder.Insert(0, charArray[(int)index].ToString());
}
return stringBuilder.ToString();
}
I've changed the char array into different one but the general method it's the same as above.
The problem is you need to use the # in front of the string literal which actually adds the backslash to the StringBuilder.
There is no point in doing #id.IdToCode(), because when the string is returned, it already contains (V\|RN. The tooltip shows \\ because it shows the escaped eversion - meaning the single backslash.
One thing that is certain is that the problem can't be resolved here, but only inside the IdToCode method, where it actually originates.
Compare this (same as your code):
static void Main(string[] args)
{
var str = IdToCode();
Console.WriteLine();
}
public static string IdToCode()
{
return "(\\VN";
}
Hovering over str I see (\\VN - two backslashes, output is just one backslash - which is correct.
And this:
static void Main(string[] args)
{
var str = IdToCode();
Console.WriteLine();
}
public static string IdToCode()
{
return #"(\\VN";
}
Here the tooltip shows "(\\\\VN" which is again correct - there are two actual backslashes and console output is the desired (\\VN

Regex for string without spacial characters or spaces [duplicate]

How do I check a string to make sure it contains numbers, letters, or space only?
In C# this is simple:
private bool HasSpecialChars(string yourString)
{
return yourString.Any(ch => ! char.IsLetterOrDigit(ch));
}
The easiest way it to use a regular expression:
Regular Expression for alphanumeric and underscores
Using regular expressions in .net:
http://www.regular-expressions.info/dotnet.html
MSDN Regular Expression
Regex.IsMatch
var regexItem = new Regex("^[a-zA-Z0-9 ]*$");
if(regexItem.IsMatch(YOUR_STRING)){..}
string s = #"$KUH% I*$)OFNlkfn$";
var withoutSpecial = new string(s.Where(c => Char.IsLetterOrDigit(c)
|| Char.IsWhiteSpace(c)).ToArray());
if (s != withoutSpecial)
{
Console.WriteLine("String contains special chars");
}
Try this way.
public static bool hasSpecialChar(string input)
{
string specialChar = #"\|!#$%&/()=?»«#£§€{}.-;'<>_,";
foreach (var item in specialChar)
{
if (input.Contains(item)) return true;
}
return false;
}
String test_string = "tesintg#$234524##";
if (System.Text.RegularExpressions.Regex.IsMatch(test_string, "^[a-zA-Z0-9\x20]+$"))
{
// Good-to-go
}
An example can be found here: http://ideone.com/B1HxA
If the list of acceptable characters is pretty small, you can use a regular expression like this:
Regex.IsMatch(items, "[a-z0-9 ]+", RegexOptions.IgnoreCase);
The regular expression used here looks for any character from a-z and 0-9 including a space (what's inside the square brackets []), that there is one or more of these characters (the + sign--you can use a * for 0 or more). The final option tells the regex parser to ignore case.
This will fail on anything that is not a letter, number, or space. To add more characters to the blessed list, add it inside the square brackets.
Use the regular Expression below in to validate a string to make sure it contains numbers, letters, or space only:
[a-zA-Z0-9 ]
You could do it with a bool. I've been learning recently and found I could do it this way. In this example, I'm checking a user's input to the console:
using System;
using System.Linq;
namespace CheckStringContent
{
class Program
{
static void Main(string[] args)
{
//Get a password to check
Console.WriteLine("Please input a Password: ");
string userPassword = Console.ReadLine();
//Check the string
bool symbolCheck = userPassword.Any(p => !char.IsLetterOrDigit(p));
//Write results to console
Console.WriteLine($"Symbols are present: {symbolCheck}");
}
}
}
This returns 'True' if special chars (symbolCheck) are present in the string, and 'False' if not present.
A great way using C# and Linq here:
public static bool HasSpecialCharacter(this string s)
{
foreach (var c in s)
{
if(!char.IsLetterOrDigit(c))
{
return true;
}
}
return false;
}
And access it like this:
myString.HasSpecialCharacter();
private bool isMatch(string strValue,string specialChars)
{
return specialChars.Where(x => strValue.Contains(x)).Any();
}
Create a method and call it hasSpecialChar with one parameter
and use foreach to check every single character in the textbox, add as many characters as you want in the array, in my case i just used ) and ( to prevent sql injection .
public void hasSpecialChar(string input)
{
char[] specialChar = {'(',')'};
foreach (char item in specialChar)
{
if (input.Contains(item)) MessageBox.Show("it contains");
}
}
in your button click evenement or you click btn double time like that :
private void button1_Click(object sender, EventArgs e)
{
hasSpecialChar(textbox1.Text);
}
While there are many ways to skin this cat, I prefer to wrap such code into reusable extension methods that make it trivial to do going forward. When using extension methods, you can also avoid RegEx as it is slower than a direct character check. I like using the extensions in the Extensions.cs NuGet package. It makes this check as simple as:
Add the [https://www.nuget.org/packages/Extensions.cs][1] package to your project.
Add "using Extensions;" to the top of your code.
"smith23#".IsAlphaNumeric() will return False whereas "smith23".IsAlphaNumeric() will return True. By default the .IsAlphaNumeric() method ignores spaces, but it can also be overridden such that "smith 23".IsAlphaNumeric(false) will return False since the space is not considered part of the alphabet.
Every other check in the rest of the code is simply MyString.IsAlphaNumeric().
Based on #prmph's answer, it can be even more simplified (omitting the variable, using overload resolution):
yourString.Any(char.IsLetterOrDigit);
No special characters or empty string except hyphen
^[a-zA-Z0-9-]+$

Returning the new string in the method

I'm newbie to c#, So i tried the below program, which will change the case of the first character of the string
public class StringBuilder
{
public static string ChangeFirstLetterCase(string inputdata)
{
if(inputdata.Length > 0)
{
char[] charArray = inputdata.ToCharArray();
charArray[0] = char.IsUpper(charArray[0]) ?
char.ToLower(charArray[0]) : char.ToUpper(charArray[0]);
//return new string(charArray);
return charArray.ToString();
}
return inputdata;
}
}
class Program
{
static void Main(string[] args)
{
var a = StringBuilder.ChangeFirstLetterCase("vishnu");
Console.WriteLine(a);
Console.ReadLine();
}
}
Since the return type of this method ChangeFirstLetterCase() is a string. So I'm just doing the conversion like below
`return charArray.ToString();`
So in the method call it is returning the System.Char[]
Alternatively I tried the below one as well
`return new string(charArray);`
So this is returning the value as expected
Argument to the method - "vishnu"
Return value - "Vishnu"
So my question here is
Since the return type of the method is string, what's wrong with below conversion?
return charArray.ToString();
How do we know when to return as new string?.
return new string(charArray);
Please provide me some example
If you return the char array as a String, it will return you the name of the object System.Char[]. This is because the ToString method of char arrays does not build the characters of the array into a usable string, but simply makes a String that states the type of object.
However, if you use new String(char[]), this will read the contents of the char array to build a string out of whatever characters are in the char array. So, you will want to use new String(char[]) for most of your String building, I cannot think of any real uses for using the ToString() on a char array.
So, for your example, you should use return new String(charArray); instead of return charArray.ToString();.
charArray.ToString(); returns the type name because it's implemented that way, for getting string back from a character array you will always have to use String class constructor.
ToString method for char[] is not implemented in a way to return the character array back as a string literal, so use String constructor as you did in the second case.
You could return:
if(inputData[0].IsLower())
return string.Concat(inputData[0].ToUpper(), inputData.Substring(1));
else
return string.Concat(inputData[0].ToLower(), inputData.Substring(1));
Your value would already be a usable string and wouldn't need to have a char[].
I'm not really sure what you gain from converting the string to a char array to being with.

c# remove duplicate char from array

static string RemoveDuplicateChars(string key)
{
// --- Removes duplicate chars using string concats. ---
// Store encountered letters in this string.
string table = "";
// Store the result in this string.
string result = "";
// Loop over each character.
foreach (char value in key)
{
// See if character is in the table.
if (table.IndexOf(value) == -1)
{
// Append to the table and the result.
table += value;
result += value;
}
}
return result;
}
The above code-snippet is from http://www.dotnetperls.com/duplicate-chars. The question I have is why do you need the extra result variable when you can just use table? Is there a reason for both variables? Below is code I wrote that accomplishes the same purpose, I believe. Am I missing anything? Thanks again and look forward to contributing here!
Code re-written:
static string RemoveDuplicateChars(string key)
{
// --- Removes duplicate chars using string concats. ---
// Store encountered letters in this string.
string table = "";
// Loop over each character.
foreach (char value in key)
{
// See if character is in the table.
if (table.IndexOf(value) == -1)
{
// Append to the table and the result.
table += value;
}
}
return table;
}
There is nothing wrong with what you did. That should work just fine. That being said, in C# we also have linq. You could just take a char[] and do:
char[] result = inputCharArray.Distinct().ToArray();
Your code is correct and functions perfectly, you could also use LINQ in C# using
stringName.Distinct()
The reason that dotnetperls uses two variables is because it is an introduction, and tries to the logic as straightforward as possible to follow to facilitate learning. Good catch!
It is not really necessary as both ways work fine. The choice is purely up to the developer.

Categories