Evan
Evan

Reputation: 13

How to make sure a string only has only certain allowed chars in it in C#

I'm making a basic calculator program that takes its inputs in the form of "num1 num2" from a user. I am working on making it so only that format of input is accepted.

This is C#. I have already tried using a whitelist array of all numbers and a space as both string[] and char[]. I have also tried Regex as well as a hybrid regex and checking for white space. none of them worked for some reason.

string input = "";
int numCheck = 0;
Regex whiteList = new Regex("^[1234567890]$");
do
{
  numCheck = 0;
  Console.Write("Please input the two numbers you wish to use seperated by a space: ");
  input = Console.ReadLine();
  if (input.IndexOf(" ") == -1 || input.Length <= 2 || input.Substring(input.IndexOf(" ")+1).IndexOf(" ") != -1 || (!whiteList.IsMatch(input) && !input.Any(x => Char.IsWhiteSpace(x))));
  {
    Console.WriteLine($"You entered \"{input}\" You did not enter two numbers seperated by a space, please try again.");
    numCheck = 1;
  }
} while (numCheck == 1);

I'm expecting an input of "1 1" to pass this check. but it does not.

Upvotes: 1

Views: 403

Answers (3)

jwatts1980
jwatts1980

Reputation: 7354

If you do not need to do a regex, something like this can work:

var values = input.Split(' ');
int value;
if (values.Length == 2 && values.All(v => int.TryParse(v, out value)) 
{
    //do stuff
}

The full solution could look like this:

string input = "";
bool success = false;
while (!success) 
{
    Console.Write("Please input the two numbers you wish to use seperated by a space: ");
    input = Console.ReadLine();

    var values = input.Split(' ', StringSplitOptions.RemoveEmptyEntries);
    if (values.Length != 2 || !values.All(v => int.TryParse(v, out int value))
    {
        Console.WriteLine($"You entered \"{input}\" You did not enter two numbers separated by a space, please try again.");
    }
    else 
    {
        success = true;
    }
}

IMHO, there is nothing wrong with the do..while but since you're already using a loop variable, I think using just while communicates better at the outset that you are entering a loop that is dependent on the success of the process below it.

Upvotes: 2

Igor
Igor

Reputation: 62308

Some changes:

  • Using string.Split is an easier way to go about getting the left/right numbers. You can then check for exactly 2 parts.
  • You need a + symbol in your regex which states 1 or more, otherwise your regular expression will test false if the integer is over 1 digit in length.

There are other ways to accomplish this same thing like using int.TryParse but this works fine for what you described you needed.


string input = "";
int numCheck = 0;
Regex whiteList = new Regex("^[1234567890]+$");
do
{
    numCheck = 0;
    Console.Write("Please input the two numbers you wish to use seperated by a space: ");
    input = Console.ReadLine();
    var numbers = input.Split(new []{' '}, StringSplitOptions.RemoveEmptyEntries);
    if (numbers.Length != 2 || !numbers.All(num => whiteList.IsMatch(num)))
    {
        Console.WriteLine("You entered " + input + " You did not enter two numbers seperated by a space, please try again.");
        numCheck = 1;
    }
}
while (numCheck == 1);

dotnetfiddle

Upvotes: 0

SGKoishi
SGKoishi

Reputation: 400

The regex should be three parts:
(number) (space) (number)
So the regex should be (\d+) (\d+).
You can also check if the length of the matched part equals the length of input - if not, it means the input contains something else.

Regex.Match(String) at MSDN

Upvotes: 0

Related Questions