This question already has answers here:
reading two integers in one line using C#
(12 answers)
Closed 8 years ago.
INPUT
67 89 (in single line)
I have to input two numbers from console , and store in two different integers variable .
HOw to do it.
This will read a line from the console, split the string, parse the integers, and output a list. You can then take each number from the list as needed.
Console.ReadLine().Split().Select(s => int.Parse(s)).ToList()
If there will always be two numbers you can do it as follows:
var integers = Console.ReadLine().Split().Select(s => int.Parse(s)).ToArray();
int first = integers[0];
int second = integers[1];
Areas for improvement:
You might want to use TryParse instead of Parse and output a friendly error message if the input does not parse
If you require exactly 2 numbers (no more, no less) you might want to check the length of integers and output a friendly error message if <> 2
TryParse() example as requested:
var numbers = new List<int>();
foreach (string s in Console.ReadLine().Split())
{
if (int.TryParse(s, out int number))
numbers.Add(number);
else
Console.WriteLine($"{s} is not an integer");
}
using System;
public class Program
{
static void Main(string[] args)
{
var numbers = Console.ReadLine();
var numberList = numbers.Split(' ');
var number1 = Convert.ToInt32(numberList[0]);
var number2 = Convert.ToInt32(numberList[1]);
Console.WriteLine(number1 + number2);
Console.ReadKey();
}
}
If you executing from other program the you need to read from the args
var result = Console.ReadLine().Split(new [] { ' '});
Something along those lines, top of my head.
See the documentation for Console.ReadLine() and String.Split()
Using Linq you can then project into an int array:
var result = Console.ReadLine()
.Split(new[] { ' ' }) //Explicit separator char(s)
.Select(i => int.Parse(i))
.ToArray();
And even a bit terser:
var result = Console.ReadLine()
.Split() //Assuming whitespace as separator
.Select(i => int.Parse(i))
.ToArray();
Result is now an array of ints.
Related
This is a question around how the compiler/language deals with this.
Take the following code:
Console.WriteLine("Enter some numbers separated by ",");
var numbers = Console.ReadLine();
var splitNumber = numbers.Split(',');
var maxNumber = splitNumber.Max();
Console.WriteLine("highest is: " + maxNumber);
Entering a string such as "1,2,3,4,5" will output the 5 as the max number.
However, using "1,2,3,55,6" outputs 6. Whereas, "33,1,4,1" gives 4. Bizarrely, "33,1,2,3" gives 33.
I know there is a better/simpler/different way of doing this using a loop. I am totally missing something with how the compiler is treating these strings to determine the output. Can someone explain it? Or provide me a reference to look it up?
In string comparison, 6 > 55 returns True.
Do this instead, Split the string into an array using Split() Extension method and then use MAX() function which Returns the maximum value in a generic sequence available in LINQ
string x = "1,2,3,55,6";
var array = x.Split(',');
Console.WriteLine("highest is: " + array.Max(c => int.Parse(c)));
Output:
highest is: 55
The "max" string is the last string in lexicographical order, i.e. the order you would list them in a dictionary
You need to use e.g. int.Parse to convert your strings to a number type if you want the numeric maximum.
You need to compare the number as ints from a list or array.
var <int> Numbers = new List<int>();
while(String had not ended)
{
var splitNumber = (int) numbers.Split(',');
Numbers.Add(splitNumner);
}
var maxNumber = Numbers.Max();
Console.WriteLine("highest is: " + maxNumber);
You can do this, Convert the string array to an array of int using ConvertAll and then find the max
Console.WriteLine("Enter some numbers separated by ");
var numbers = Console.ReadLine();
var splitNumber = numbers.Split(',');
int[] myInts = Array.ConvertAll(splitNumber, int.Parse);
var maxNumber = myInts.Max();
Console.WriteLine("highest is: " + maxNumber);
I tried compiling your code with same inputs. I have also getting the same output but i thing when u try to perform .Max() operation on a string array it is only comparing the first character of each entries in your second array.
If the input is 1,2,3,55,6 you are gonna get the output as 6 because when you compare all the numbers and there first digit 6 is the largest. But if you change the input to 1,2,3,75,6 now you are gonna get the output as 75 because 7 is the biggest first digit of all the numbers in the list.
string str = "1,2,3,75,6";
var splitNumber = str.Split(',');
var maxNumber = splitNumber.Max();
Like all the other answers u need to convert the string array into an integer array and then apply it.
Ans for how the compiler is treating these strings to determine the output?:
As these are strings, string equality gets checked for it.
The compiler takes each string value and compares it to one by one char. It deduces equality on the first occurrence of mismatch (e.g. in 55 vs 6, 5 is less than 6, hence 55 is less than 6)
You can use this :
Console.WriteLine("Enter a series of number separated by comma and I will tell you which one is the biggest, cool!");
var input = Console.ReadLine().Split(',');
Console.WriteLine("Biggest is :" + input.Max(c => int.Parse(c)));
You can also do this:
var splitNumber = numbers.Split(',').Select(c=>Convert.ToInt32(c)).Max();
Console.WriteLine("highest is: " + splitNumber);
change Var to Int64
Int64 maxNumber = Int64.Parse(splitNumber.Max());
trying to select the max digit from a list of strings:
int maxDigit = this.myList.Where(x=> x.Name.Any(Char.IsDigit))
.Select(x => int.Parse(x.Name)).DefaultIfEmpty(0).Max();
It is int.Parse(x.Name) which is causing an exception as this is returning the entire name string e.g. 'myValue99' which of course cannot be parsed to an int. I just want to return 99. I don't know where the digits will be in the string therefore cannot for example take the last two.
I need the DefaultIfEmpty for cases where the string does not contain a number.
Assuming you want the max number and not the max digit, all you need is a function to convert "stuff99" to 99. Then the Linq part becomes child's play:
int maxNumber = myList.Max(ExtractNumberFromText);
or, to be closer to your specs:
int maxNumber = myList
.Select(ExtractNumberFromText)
.DefaultIfEmpty(0)
.Max();
#Codecaster already pointed to a few applicable answers on this site for the second part. I adopted a simple one. No error checking.
// the specs: Only ever going to be my stuff1, stuff99
int ExtractNumberFromText(string text)
{
Match m = Regex.Match(text, #"\d*");
return int.Parse(m.Groups[0].Value); // exception for "abc"
// int.Parse("0" + m.Groups[0].Value); // use this for default to 0
}
you should only select and parse the Digit characters out of your string
int maxDigit = this.myList.Where(x => x.Name.Any(Char.IsDigit))
.Select(x => int.Parse(new string(x.Name.Where(Char.IsDigit).ToArray())))
.DefaultIfEmpty(0).Max();
Assuming the input can contain the following categories:
nulls
Empty strings
Strings with only alphabetical characters
Strings with mixed alphabetical and numerical characters
Strings with only numerical characters
You want to introduce a method that extracts the number, if any, or returns a meaningful value if not:
private static int? ParseStringContainingNumber(string input)
{
if (String.IsNullOrEmpty(input))
{
return null;
}
var numbersInInput = new String(input.Where(Char.IsDigit).ToArray());
if (String.IsNullOrEmpty(numbersInInput))
{
return null;
}
int output;
if (!Int32.TryParse(numbersInInput, out output))
{
return null;
}
return output;
}
Note that not all characters for which Char.IsDigit returns true can be parsed by Int32.Parse(), hence the TryParse.
Then you can feed your list to this method:
var parsedInts = testData.Select(ParseStringContainingNumber)
.Where(i => i != null)
.ToList();
And do whatever you want with the parsedInts list, like calling IEnumerable<T>.Max() on it.
With the following test data:
var testData = new List<string>
{
"۱", // Eastern Arabic one, of which Char.IsDigit returns true.
"123",
"abc456",
null,
"789xyz",
"foo",
"9bar9"
};
This returns:
123
456
789
99
Especially note the latest case.
To find the max digit (not number) in each string:
static void Main(string[] args)
{
List<string> strList = new List<string>() { "Value99", "46Text" };
List<int> resultList = new List<int>();
foreach (var str in strList)
{
char[] resultString = Regex.Match(str, #"\d+").Value.ToCharArray();
int maxInt = resultString.Select(s => Int32.Parse(s.ToString())).Max();
resultList.Add(maxInt);
}
}
It can be simple using Regex.
You stated 99, so you need to span more than one digit:
var maxNumber = myTestList.SelectMany(x => getAllNumnbersFromString(x.Name)).DefaultIfEmpty(0).Max();
static List<int> getAllNumnbersFromString(string str)
{
List<int> results = new List<int>();
var matchesCollection = Regex.Matches(str, "[0-9]+");
foreach (var numberMatch in matchesCollection)
{
results.Add(Convert.ToInt32(numberMatch.ToString()));
}
return results;
}
One digit only check:
int maxNumber = myTestList.SelectMany(x => x.Name.ToCharArray().ToList())
.Select(x => Char.IsDigit(x) ? (int)Char.GetNumericValue(x) : 0)
.DefaultIfEmpty(0).Max();
Probably there's a slicker way to do this but I would just do:
int tmp = 0;
int maxDigit = this.myList.Where(x=> x.Name.Any(Char.IsDigit))
.Select(x =>
(int.TryParse(x.Name,out tmp ) ? int.Parse(x.Name) : 0 ) ).Max();
You have to remember that Parse will error out if it can't parse the value but TryParse will just give you false.
I know that this will extract the number and store as int -
string inputData = "sometex10";
string data = System.Text.RegularExpressions.Regex.Match(inputData, #"\d+").Value;
int number1 = Convert.ToInt32(data);
I am trying to extract multiple numbers from a string eg- 10 + 2 + 3 and store these as separate integers.
note : the amount of numbers the user will type in is unknow.
Any suggestions much appreciated thanks
You can use a LINQ one-liner:
var numbers = Regex.Matches(inputData, #"\d+").Select(m => int.Parse(m.Value)).ToList();
Or use ToArray() if you prefer an array instead of a list.
C# program that uses Regex.Split
Referencing : http://www.dotnetperls.com/regex-split
using System;
using System.Text.RegularExpressions;
class Program
{
static void Main()
{
//
// String containing numbers.
//
string sentence = "10 cats, 20 dogs, 40 fish and 1 programmer.";
//
// Get all digit sequence as strings.
//
string[] digits = Regex.Split(sentence, #"\D+");
//
// Now we have each number string.
//
foreach (string value in digits)
{
//
// Parse the value to get the number.
//
int number;
if (int.TryParse(value, out number))
{
Console.WriteLine(number);
}
}
}
}
You can use something like this:
string inputData = "sometex10";
List<int> numbers = new List<int>();
foreach(Match m in Regex.Matches(inputData, #"\d+"))
{
numbers.Add(Convert.ToInt32(m.Value));
}
This will store the integers in the list numbers
I am trying to parse a string into array and find a very concise approach.
string line = "[1, 2, 3]";
string[] input = line.Substring(1, line.Length - 2).Split();
int[] num = input.Skip(2)
.Select(y => int.Parse(y))
.ToArray();
I tried remove Skip(2) and I cannot get the array because of non-int string. My question is that what is the execution order of those LINQ function. How many times is Skip called here?
Thanks in advance.
The order is the order that you specify. So input.Skip(2) skips the first two strings in the array, so only the last remains which is 3. That can be parsed to an int. If you remove the Skip(2) you are trying to parse all of them. That doesn't work because the commas are still there. You have splitted by white-spaces but not removed the commas.
You could use line.Trim('[', ']').Split(','); and int.TryParse:
string line = "[1, 2, 3]";
string[] input = line.Trim('[', ']').Split(',');
int i = 0;
int[] num = input.Where(s => int.TryParse(s, out i)) // you could use s.Trim but the spaces don't hurt
.Select(s => i)
.ToArray();
Just to clarify, i have used int.TryParse only to make sure that you don't get an exception if the input contains invalid data. It doesn't fix anything. It would also work with int.Parse.
Update: as has been proved by Eric Lippert in the comment section using int.TryParse in a LINQ query can be harmful. So it's better to use a helper method that encapsulates int.TryParse and returns a Nullable<int>. So an extension like this:
public static int? TryGetInt32(this string item)
{
int i;
bool success = int.TryParse(item, out i);
return success ? (int?)i : (int?)null;
}
Now you can use it in a LINQ query in this way:
string line = "[1, 2, 3]";
string[] input = line.Trim('[', ']').Split(',');
int[] num = input.Select(s => s.TryGetInt32())
.Where(n => n.HasValue)
.Select(n=> n.Value)
.ToArray();
The reason it does not work unless you skip the first two lines is that these lines have commas after ints. Your input looks like this:
"1," "2," "3"
Only the last entry can be parsed as an int; the initial two will produce an exception.
Passing comma and space as separators to Split will fix the problem:
string[] input = line
.Substring(1, line.Length - 2)
.Split(new[] {',', ' '}, StringSplitOptions.RemoveEmptyEntries);
Note the use of StringSplitOptions.RemoveEmptyEntries to remove empty strings caused by both comma and space being used between entries.
I think it would be better you do it this way:
JsonConvert.DeserializeObject(line, typeof(List<int>));
you might try
string line = "[1,2,3]";
IEnumerable<int> intValues = from i in line.Split(',')
select Convert.ToInt32(i.Trim('[', ' ', ']'));
Hi how do you extract multiple decimals with different number of decimal places from a string?
I'm looking to find a generic way to extract 3 numbers out the following strings.
e.g
CC77X1722X12 => 77,1722,12
PC77.5X10102X12.5 => 77.5, 10102, 12.5
XP60.25X0.333X12 => 60.25, 0.333, 12
The three numbers are always separated by 'X', and the string always starts with 2 characters
Thanks!
Since you have such a specific pattern, you don't even need to use regular expressions. Because the first two characters can be ignored and all the numbers are separated by 'X' characters, this C# code should do the trick (with appropriate error handling added, of course)
public IEnumerable<decimal> ExtractNumbers(string s)
{ // For s = "CC77X1722X12"
string[] nums = s.Substring(2).Split('X'); // nums = ["77", "1722", "12"];
return nums.Select(num => decimal.Parse(num)); // returns [77, 1722, 12]
}
For production code, though, I would recommend decimal.TryParse over decimal.Parse. To use that method, you could write something like
public IEnumerable<decimal> ExtractNumbers(string s)
{
string[] nums = s.Substring(2).Split('X');
return nums
.Select(num => {
decimal d;
if (decimal.Parse(num, out d))
return new {Number = d, Succeeded = true};
return new {Number = 0, Succeeded = false};
})
.Filter(result => result.Succeeded)
.Select(result => result.Number);
}