I'm making a program that reverses a string and doesn't allow for anything else than letters and whitespaces, problem is that if i enter a non-valid input and then try to input a valid input it just keeps printing error. I think the problem has something to do with my while loop and the bool result, but i can't figure it out. Please help and thank you!
static void Reverse()
{
string name;
Console.Write("Enter your name: ");
name = Console.ReadLine();
bool result = name.All(c => char.IsWhiteSpace(c) || char.IsLetter(c));
if (Regex.IsMatch(name, #"^[a-zA-Z- ]+$")) // Validates the input for characters and/or spaces
{
char[] charArr = name.ToCharArray();
Array.Reverse(charArr);
string nameRev = new string(charArr);
Console.WriteLine("String is {0}", nameRev);
}
else
{
while (name == String.Empty || result == false) //Should validate the input for whitespace or letter if it doesn't pass the first validation
{
Console.Write("Error! Enter your name, only letters allowed: ");
name = Console.ReadLine();
}
}
You need to wrap your while loop around the hole sequence instead of just having it inside the else statement.
Example:
static void Reverse()
{
// Continues executing as long as result stays false.
bool result;
do
{
string name;
Console.Write("Enter your name: ");
name = Console.ReadLine();
result = name.All(c => char.IsWhiteSpace(c) || char.IsLetter(c));
if (Regex.IsMatch(name, #"^[a-zA-Z- ]+$"))
{
char[] charArr = name.ToCharArray();
Array.Reverse(charArr);
string nameRev = new string(charArr);
Console.WriteLine("String is {0}", nameRev);
}
else
{
Console.WriteLine("Error! Only letters allowed");
}
}
while (!result);
}
Related
I am building an e-mail validation program.
How can I check if my E-Mail has 3 letters before the # and 2 letters after the "." I tried else if but it didn't work.
string rightPassword = "red#gmx.to";
string enter = Console.ReadLine();
string red = rightPassword.Substring(0, 3);
string to = rightPassword.Substring(8);
int lengthRed = red.Length;
int lengthTo = to.Length;
do
{
Console.Write("Write the E-Mail: ");
enter = Console.ReadLine();
if (rightPassword == enter)
{
Console.WriteLine("Right Password");
}
else if (lengthRed < 3 ) // I have to check if it has 3 letters before the #//
{
Console.WriteLine("You need 3 letters before the #")
}
else if (lengthTo < 2)
{
Console.WriteLine("You need 2 letter after the ".")
}
} while (enter != "enter");
Just use Regular expressions for pattern matching.
You should use this regex to achieve what you want: ^\w{3}#\w+.\w{2}$
code example:
string email = "abc#aa.co";
Regex regex = new Regex(#"^\w{3}#\w+.\w{2}$");
Match match = regex.Match(email);
if(match.Success)
Console.WriteLine("Email matches pattern");
else Console.WriteLine("Email does not matches pattern");
If you don't want to use Regular Expressions, even though it is highly encouraged, you can add a method:
public static bool HasValidUsername(string email)
{
for (int i = 0; i < 3; i++)
{
if (!email[i].IsLetter())
{
return false;
}
}
return true;
}
And use the method in your code:
else if (!HasValidUsername(enter))
{
Console.WriteLine("You need 3 letters before the #");
}
But keep in mind, that the example above will not validate numbers or symbols. You could use email[i].IsSymbol() or email[i].IsNumber() to check for that.
Note:
x#com is a valid email adress for a domain registrar. That said, most of them use a subdomain for their email. x#x.com for example. Handling all real world email cases is not as trivial as it might seem.
Using Char.IsLetter() method
public bool IsValidEmail(string email)
{
return email.Length > 2 Char.IsLetter(str[0]) && Char.IsLetter(str[1]) && Char.IsLetter(str[2]);
}
You could also use Split.
Something like
string red = rightPassword.Split('#')[0];
string to = rightPassword.Split('.').Last();
you'll also be able to check what's after the "#" if you use
string red = rightPassword.Split('#')[0];
string gmx= rightPassword.Split('#')[1];
string to = rightPassword.Split('.').Last();
Hi so im trying to validate my string here so that it does not allow any input that starts with: "911" so if you type: "9 11", "91 1", "9 1 1" it should go through my if statement. It works with "911" but not the others, here's my code:
using System;
using System.Collections.Generic;
namespace Phone_List
{
class Program
{
static void Main(string[] args)
{
var phoneList = new List<string>();
string input;
Console.WriteLine("Input: ");
while ((input = Console.ReadLine()) != "")
{
phoneList.Add(input);
for (int i = 0; i < phoneList.Count; i++)
{
if (phoneList[i].Substring(0, 3) == "911")
{
input.StartsWith("9 11");
input.StartsWith("9 1 1");
input.StartsWith("91 1");
Console.WriteLine("NO");
Console.ReadLine();
return;
}
else
{
Console.WriteLine("YES");
Console.ReadLine();
return;
}
}
}
}
}
}
As you can see I am trying to use "input.StartsWith("9 11");" but it does not work...
You could use the Replace method of String; the condition you describe can be formulated as follows.
input.Replace(" ", "").StartsWith("911")
Use regular expressions for checks like this.
For example:
Regex.IsMatch(input, "^\\s*9\\s*1\\s*1");
This regex matches all strings that include whitespaces in front of and between "911".
Use the following to check if the string starts with "911":
First create a copy from the input string but without any white spaces:
string input_without_white_spaces =
new string(input.ToCharArray().Where(x => !char.IsWhiteSpace(x)).ToArray());
Then you can check if the string starts with 911 like this:
if (input_without_white_spaces.StartsWith("911"))
{
...
}
bool valid = s.StartsWith("911") ||
!string.Join("",s.Split()).StartsWith("911");
I'm trying to use a method to validate a string that has two capital letters at the start and 3 digits after that. The one I am writing at the minute is:
static void Main(string[] args)
{
Console.WriteLine("Enter stock quantity:");
string qty = Console.ReadLine();
string code = enterStockCode();
}
static string enterStockCode()
{
string[] pLetters = new string[] { "BL", "FS", "HJ", "PX" };
bool isValid = false;
while (isValid == false)
{
Console.WriteLine("Enter stockcode:");
string stockCode = Console.ReadLine();
char[] stockCodeSplit = stockCode.ToCharArray();
var vLetters = (stockCodeSplit[0] + stockCodeSplit[1]);
var vNumbers = (stockCodeSplit[2] + stockCodeSplit[3] + kCodeSplit[4]);
// I'd like to know if there is a better way of splitting this string
// by using regular expressions or another way.
foreach (var Letter in pLetters)
{
if (vNumbers.ToString() == Letter)
{
if (Regex.Match(vNumbers.ToString(), #"^\d[0-9]{2}$").Success)
return stockCode;
Console.WriteLine("Invalid stock code");
}
}
}
return "Invalid";
}
(Also I would like to know if the "2" in:
#"^\d[0-9]{2}$"
means 2 times or three times as c# uses index of 0.)
Any help at all is appreciated.
please try:
^[A-Z]{2}\d{3}
If you just want to find an expression starting with 2 capital letters followed by 3 digits you should not put an ending limiter, just the starting.
The 2 means 2 times.
I'm making a console app in which I'll ask the user for a phone number int main_phone, but if he types a string thats not convertible to int such as "Caramel" I want to give him a warning and ask for a number.
Well I thought a recursive function would do, but I'm lacking logical aptitude for this one. What I came up with was the following code snippet:
static int? TryParse(string str)
{
int tmp;
if (int.TryParse(str, out tmp)) {
return tmp;
}
return null;
}//End of TryParse();
static int? verifyParse(string str, string lable)
{
int? testedVar = TryParse(str);
if (testedVar == null)
{
Console.WriteLine("Este campo pode apenas conter dígitos de 0 à 9.");
Console.Write(lable);
verifyParse(Console.ReadLine(), lable);
return null;
}
else
{
return testedVar;
}
}//End of verifyParse();
Console.Write("Phone(main):");
int? main_phone = verifyParse(Console.ReadLine(),"Telefone (Principal):");
The problem is that if the user inputs "string" main_phone will comeback as null, then it asks for a number between 0 and 9, but even if the user passes a convertible string , such as "12", main_phone will still be null.
How can I fix that?
EDIT 1:
What I really need is a function that if the string can be converted to an int it returns the int, else it gives me an error and asks me to input something between 0 and 9. I find this hard because the function would have to be able to return an int or run it self all over again(to require and test a valid input), but it can't because either it returns the int or it doesn't return nothing.
EDIT 2:
Here is a little update on my problem:
static int TryParse(string lable)
{
string str = Console.ReadLine();
Regex regex = new Regex(#"\d+");
while (!regex.IsMatch(str))
{
Console.WriteLine("Insira apenas dígitos de 0-9, por favor.");
Console.Write(lable);
str = Console.ReadLine();
}
return Convert.ToInt32(str);
}//End of TryParse();
Console.Write("Telefone (Principal):");
int main_phone = TryParse("Telefone (Principal):");
It works really well, except when I input something like "1a". In that case I'll get this error:
System.FormatException: Input string was not in a correct format.
at System.Number.StringToNumber(String str, NumberStyles options, NumberBuffer& number, NumberFormatInfo info, Boolean parseDecimal)
at System.Number.ParseInt32(String s, NumberStyles style, NumberFormatInfo info)
at System.Convert.ToInt32(String value)
at App1.Program.TryParse(String lable)
at App1.Program.Main(String[] args)
Here's a solution that loops until a good match is produced, using regex validation
Regex regex = new Regex(#"\d{3}-?\d{3}-?\d{4}");
string phonenumber = Console.ReadLine();
while (!regex.IsMatch(phonenumber))
{
Console.WriteLine("Bad Input");
phonenumber = Console.ReadLine();
}
return Convert.ToInt32(phonenumber.Replace("-",""));
which will match 5555555555 and 555-555-5555, and return the int value.
How about you just read in as a string what the user puts in, replace all "-" with "", then check if it numeric and check length. No need to make a recursive method for such a simple task.
how about this
[VB.NET]
Function CheckPhoneNumber(ByVal Number As String) As String
Number = Number.Replace("-","")
Number = Number.Replace("(","")
Number = Number.Replace(")","")
If Not IsNumeric(Number) Then
Return "Error"
Else
Return Number
End If
End Function
[C#]
public string CheckPhoneNumber(string Number)
{
Number = Number.Replace("-", "");
Number = Number.Replace("(", "");
Number = Number.Replace(")", "");
if (!Information.IsNumeric(Number)) {
return "Error";
} else {
return Number;
}
}
What about just using int.TryParse?
void Main()
{
var input = Console.ReadLine();
int phone;
while(!int.TryParse(input, out phone)){
Console.WriteLine("Please enter a number");
input = Console.ReadLine();
}
Console.WriteLine("Success");
}
To cleanup the input, you can replace the "-"
var input = Console.ReadLine().Replace("-", "");
Could strip out any extra characters ('+', '-', '#', '(', ')', and '*') then try
bool successful;
int result;
if(!int.tryparse(string, result))
{
Console.WriteLine("Invalid phone number");
}
else
{
Console.WriteLine("Valid phone number");
}
Or whatever you like.
Of course the alternative is to use REGEX. (note: I'm stealing this from Regex Hero found here: http://regexhero.net/tester/)
string strRegex = #"[+]?[\d][\d\s()-.]{8,}[\d]";
RegexOptions myRegexOptions = RegexOptions.None;
Regex myRegex = new Regex(strRegex, myRegexOptions);
foreach (Match myMatch in myRegex.Matches(strTargetString))
{
if (myMatch.Success)
{
// Add your code here
}
}
Try this modified version of your code segment:
static int? verifyParse(string str, string lable)
{
int? testedVar = TryParse(str);
if (testedVar == null)
{
Console.WriteLine("Este campo pode apenas conter dígitos de 0 à 9.");
Console.Write(lable);
int? newVal = verifyParse(Console.ReadLine(), lable);
if (newVal != null)
return newVal;
else
return null;
}
else
{
return testedVar;
}
}//End of verifyParse();
I am trying to display my results as follows:
-.-|- [tab] kt
-.|-- [tab] nm
-.|-|- [tab] ntt
But this is my current output
-.-|-| kt
-.|--| nm
-.|-|-| [tab]ntt
There is a | at the end of every Morse code which I would like to remove since it is at the end.
Also because the user can input Morse code with space between dots and dashes - i noticed that it affects the alignment of the characters and not all of them get tabbed properly. The word tab isn't supposed to show i just wrote it in because I didn't know how to place a real tab.
private static readonly IDictionary<char, string> morseCode_alpha = new Dictionary<char, string>
{
{'a', ".-"},{'b',"-..."}, {'c',"-.-."}, {'d',"-.."}, {'e',"."},
{'f',"..-."}, {'g',"--."}, {'h',"...."},{'i',".."}, {'j',".---"},
{'k',"-.-"}, {'l',".-.."}, {'m',"--"}, {'n',"-."}, {'o',"---"},
{'p',".--."}, {'q',"--.-"}, {'r',".-."}, {'s',"..."}, {'t',"-"},
{'u',"..-"}, {'v',"...-"}, {'w',".--"}, {'x',"-..-"}, {'y',"-.--"}, {'z',"--.."}
};
private static string ConvertMorseToText(string symbolCode)
{
var builder = new StringBuilder(4 * symbolCode.Length);
foreach (char c in symbolCode)
builder.Append(morseCode_alpha[c]);
return builder.ToString();
}
private static string ConvertTextToMorse(char ch)
{
if (morseCode_alpha.Keys.Contains(ch))
return morseCode_alpha[ch];
else
return string.Empty;
}
private static string ConvertStringToMorse(string letters)
{
StringBuilder sb = new StringBuilder();
foreach (char ch in letters)
{
if (sb.Length != 0 && sb[sb.Length - 1] != ' ')
sb.Append("|");
sb.Append(ConvertTextToMorse(ch));
}
return sb.ToString();
}
private static IEnumerable<string> Permutations( string symbolCode)
{
int n = symbolCode.Length;
if (n == 0 || symbolCode.Length == 0)
yield return " ";
else
foreach (var entry in morseCode_alpha)
if (symbolCode.StartsWith(entry.Value))
foreach (string next in Permutations(symbolCode.Substring(entry.Value.Length)))
yield return entry.Key + next;
}
private static void Write( string rest)
{
string result = ConvertStringToMorse(rest);
Console.Write(result+"\t");
Console.WriteLine(rest);
}
static void Main(string[] args)
{
string morseInput;
string entered = "";
do
{
Console.WriteLine("Enter Morse Code: \n");
morseInput = Console.ReadLine().Replace(" ","");
bool isValid = Regex.IsMatch(morseInput, #"^[-.]+$");
if (isValid)
{
Console.WriteLine("\nAll permutations:\n");
string morse = ConvertMorseToText(entered);
string permutations = morseInput.Substring(morse.Length);
Write(permutations);
var nexts = new List<string>(Permutations(permutations));
foreach (string next in nexts)
Write(next);
}
else
{
Console.WriteLine("\nFormat of morse must be only dots and dashes.");
Console.WriteLine("Parameter name: "+morseInput+"\n");
}
}
while (morseInput.Length != 0);
}
And, to answer the other part of the question...
Tabstops are fixed for console writing, so it would be better to use something like String.PadRight
so, your code could be:
private static void Write(string rest)
{
string result = ConvertStringToMorse(rest);
Console.Write(result.PadRight(20));
Console.WriteLine(rest);
}
Draft version of the method:
private static string ConvertStringToMorse(string letters)
{
var result = string.Join("|",
letters
.Select(ConvertTextToMorse)
.Where(morse => !string.IsNullOrEmpty(morse)));
return result;
}
Update:
Please note that the entered variable is used only once: when defined - empty string is assigned. Then the ConvertMorseToText(entered) method is called: it always returns empty string for the empty string argument. After this assignment string permutations = morseInput.Substring(morse.Length); the permutations variable will store exactly the same value as morse variable (because morse.Length is always 0).
So, it seems that the entered variable and the ConvertMorseToText() method are useless (both can be safely removed):
static void Main(string[] args)
{
do
{
Console.WriteLine("Enter Morse Code: ");
string morseInput = Console.ReadLine();
if (string.IsNullOrWhiteSpace(morseInput))
{
// Empty or consists only of white-space characters
break;
}
morseInput = morseInput.Replace(" ", "");
bool isValid = Regex.IsMatch(morseInput, #"^[-.]+$");
if (isValid)
{
Console.WriteLine("All permutations:");
Console.WriteLine();
var nexts = Permutations(morseInput).ToList();
foreach (string next in nexts)
Write(next);
}
else
{
Console.WriteLine();
Console.WriteLine("Format of morse must be only dots and dashes.");
Console.WriteLine("Parameter name: {0}", morseInput);
}
}
while (true);
}
Update 2:
Consider using TryGetValue() method of Dictionary<TKey, TValue> instead of Keys.Contains and [] (indexer) i.e. do not perform look-up twice:
private static string ConvertTextToMorse(char ch)
{
string result;
return morseCode_alpha.TryGetValue(ch, out result) ? result : string.Empty;
}
Instead this code:
Console.Write(result+"\t");
Console.WriteLine(rest);
Use
Console.WriteLine("{0,-10}{1,-10}", result, rest);
Then you will see two columns (each max 10 charachters) with left alignment. Or remove "-" sign if you want right alignment.