I am learning C# and having an issue understanding why my highNumber value is being displayed as 56 when running my code snippet.
//Write a program and ask the user to enter a series of numbers separated by comma. Find the maximum of the numbers
//and display it on the console. For example, if the user enters “5, 3, 8, 1, 4", the program should display 8
int highNumber = 0;
Console.Write("Enter a series of numbers separated by comma: ");
var userInput = Console.ReadLine();
for (var i = 0; i < userInput.Length; i++)
{
if (char.IsNumber(userInput[i]) == true)
{
if (userInput[i] > highNumber)
{
highNumber = Convert.ToInt32(userInput[i]);
}
}
}
Console.WriteLine("The largest number is {0}", Convert.ToInt32(highNumber));
You've entered the ASCII character '8', which has the numeric value 56.
If it's a single digit character then convert it with this
int val = (int)Char.GetNumericValue(userInput[i]);
If it's a numeric string then convert it in one call with this
int val;
bool success = Int32.TryParse(userInput, out val);
or
int val = System.Convert.ToInt32(userInput);
The LordWilmore`s answer is somehow correct if you dont use numbers greater than 10 but you can simplify and make it more accurate as below:
int highNumber = 0;
int valueTemp;
Console.Write("Enter a series of numbers separated by comma: ");
var userInput = Console.ReadLine();
string[] array = userInput.Split(',');
for (var i = 0; i < array.Length; i++)
{
if (int.TryParse(array[i], out valueTemp))
{
if (valueTemp > highNumber)
{
highNumber = valueTemp;
}
}
}
Console.WriteLine("The largest number is {0}", highNumber);
or using Max() function if you have knowledge about the List<> in c#:
int valueTemp;
Console.Write("Enter a series of numbers separated by comma: ");
var userInput = Console.ReadLine();
string[] array = userInput.Split(',');
List<int> intList = new List<int>();
for (var i = 0; i < array.Length; i++)
{
if (int.TryParse(array[i], out valueTemp))
{
intList.Add(valueTemp);
}
}
Console.WriteLine("The largest number is {0}", intList.Max());
This is a more accurate example because if put 3,33,4 in your example it will fail since you get each character and not values separated by comma. In my case I split them into pieces accordingly and then continue to test them appropriately.
Console.ReadLine(); returns a string. When you use the indexer ([i]) on the string you get individual characters, not strings or numbers. What you want is to Split the string by the commas, then use TryParse to ensure that each string is a number:
string userInput = Console.ReadLine();
string[] parts = userInput.Split(',');
for (var i = 0; i < parts.Length; i++)
{
int number;
if (int.TryParse(parts[i], out number))
{
if (number > highNumber)
{
highNumber = number;
}
}
}
Related
Task:
The program asks the user to enter the text, after entering the text, the program declares how many words are in the text. It also counts the amount of digits in the text and displays it on the screen.
static void Main(string[] args)
{
Console.Write("Insert text: ");
string s = Console.ReadLine();
int count = 1, num, sum = 0, r;
for (int i = 1; i < s.Length; i++)
{
if (Char.IsWhiteSpace(s[i]))
{
count++;
}
}
num = int.Parse(Console.ReadLine());
while (num != 0)
{
r = num % 10;
num = num / 10;
sum = sum + r;
}
Console.WriteLine("Sum of Digits of the Number : " + sum);
Console.WriteLine("In text {1} names", s, count);
}
The program asks for the text and numbers to be entered. The numbers in the text are counted why doesnt it work correctly?
As per the input/output described in the comment, You do not need a second ReadLine Statement. You can do as follows.
static void Main(string[] args)
{
Console.WriteLine("Enter Text");
var userEntry = Console.ReadLine();
var countOfWords = userEntry.Split(new []{" "},StringSplitOptions.RemoveEmptyEntries).Count();
var sum = userEntry.Where(c => Char.IsDigit(c)).Select(x=>int.Parse(x.ToString())).Sum();
Console.WriteLine($"Count Of Words :{countOfWords}{Environment.NewLine}Sum :{sum}");
}
This is in the case when(as per your comment), the input string is "xsad8 dlas8 dsao9", for which the sum would be 25.
If the input string is "xsad8 dlas81 dsao9" and you want to treat 81 as '81', rather than 8 & 1, the Sum can be calculated as follows.
var sum = Regex.Split(userEntry, #"\D+").Where(s => s != String.Empty).Sum(x=>int.Parse(x));
Sum in above case would be 98
Try this code. I hope it will help you.
using System;
namespace SimpleProblem
{
class Program
{
static void Main(string[] args)
{
// Task:
// The program asks the user to enter the text, after
// entering the text, the program declares how many words
// are in the text. It also counts the amount of digits in
// the text and displays it on the screen.
Console.WriteLine("Enter a Text");
string word = Console.ReadLine();
int wordCount = 0;
char[] wordsArray = word.ToCharArray();
foreach (var item in wordsArray)
{
//Counting the number of words in array.
wordCount = wordCount + 1;
}
Console.WriteLine("Entered Text: " + word);
Console.WriteLine("No. of Counts: " + wordCount);
}
}
}
I am trying to get input from user 5 times and add those values to marks array;
Then, it will calculate the average and print positive or negative accordingly. However, I can not take input from the user it just prints "Enter 5 elements". After getting input from user how can I add them to marks array? Any tips would be helpful.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text.RegularExpressions;
class Program
{
static void Main()
{
double average =0;
int [] marks = new int[] { };
for (int a = 0; a < 5; a++){
Console.WriteLine("Enter 5 elements:");
string line = Console.ReadLine();
Console.WriteLine(line);
}
for (int i = 0; i < marks.Length; i++){
average = marks.Average();
}
if(average>0){
Console.WriteLine("Positive");
}else{
Console.WriteLine("Negative");
}
}
}
I would use a while loop combined with int.TryParse to check if the user input is a number. Also it doesn't make any sense to put average = marks.Average(); inside a for loop, because LINQ Average calculates the average of a collection (in your case the marks array).
static void Main()
{
int[] marks = new int[5];
int a = 0;
Console.WriteLine("Enter 5 elements:");
while (a < 5)
{
if (int.TryParse(Console.ReadLine(), out marks[a]))
a++;
else
Console.WriteLine("You didn't enter a number! Please enter again!");
}
double average = marks.Average();
if (average > 0)
Console.WriteLine("Positive");
else
Console.WriteLine("Negative");
}
DEMO HERE
Edited my answer to illustrate solving your problem without a for loop.
class Program
{
const int numberOfMarks = 5;
static void Main()
{
List<int> marks = new List<int>();
Enumerable.Range(1, numberOfMarks)
.ForEach((i) => {
Console.Write($"Enter element {i}:");
marks.Add(int.TryParse(Console.ReadLine(), out var valueRead) ? valueRead : 0);
Console.WriteLine($" {valueRead}");
});
Console.WriteLine(marks.Average() >= 0 ? "Positive" : "Negative");
}
}
This will help you, just copy and paste it.
There are some explanation with comments.
class Program
{
static void Main()
{
const int numberOfMarks = 5;
int[] marks = new int[numberOfMarks];
Console.WriteLine("Enter 5 elements:");
for (int a = 0; a < numberOfMarks; a++)
{
// If entered character not a number, give a chance to try again till number not entered
while(!int.TryParse(Console.ReadLine(), out marks[a]))
{
Console.WriteLine("Entered not a character");
}
Console.WriteLine("You entered : " + marks[a]);
}
// Have to call Average only once.
var avg = marks.Average();
Console.WriteLine(avg > 0 ? "Positive average" : "Negative average");
Console.ReadLine();
}
}
Follow Stackoverflow Answer
since integer array is being used, and as input from the console is a string value, you need to convert it using Parse() Method. For e.g.
string words = "83";
int number = int.Parse(words);
Edit: using string variable in parsing.
I'm making a program that accepts values into an array, but if you attempt to input the same value twice, it rejects, if the value is unique, go on.
using System;
public class Program
{
public static void Main()
{
char[] charray = new char[7];
Console.WriteLine("Enter 7 unique alphabetic characters: ");
for (int i = 0; i < charray.Length; i++)
{
charray[i] = Convert.ToChar(Console.ReadLine());
for (int j = 0; j < charray.Length; j++)
{
if (charray[i] == charray[j])
{
Console.WriteLine("Please enter a unique alphabetic character.");
}
}
}
Console.WriteLine(charray);
}
}
Can someone tell me what's wrong?
you're comparing every element in your array with what you just assigned to an element in your array, so of course you'll always find a duplicate... with the item you just entered.
What you actually want is:
void Main()
{
char[] charray = new char[7];
Console.WriteLine("Enter 7 unique alphabetic characters: ");
for (int i = 0; i < charray.Length; i++)
{
var x = Convert.ToChar(Console.ReadLine());
if (charray.Contains(x))
{
Console.WriteLine("Please enter a unique alphabetic character.");
i--;
}
else
{
charray[i] = x;
}
}
Console.WriteLine(charray);
}
By the way this approach is quite slow specially if you extend your array, 7 is fine but the level of optimization is very poor, you might want to look at concept of Hash map. And like the others said, since you first insert the input inside your array, the for will always find your input inside and return duplicated, you might want to check the duplication before insertion operation.
I would like to propose the following implementation:
char[] charArray = new char[7];
Console.WriteLine("Enter {0} unique alphabetic characters: ", charArray.Length);
int i = 0;
while (i < charArray.Length)
{
char inputChar = Console.ReadKey().KeyChar;
Console.WriteLine();
if (charArray.Contains(inputChar))
{
Console.WriteLine("Please enter a unique alphabetic character.");
}
else
{
charArray[i] = inputChar;
++i;
}
}
Console.WriteLine(charArray);
Not entirely sure this is possible, but say I have two strings like so:
"IAmAString-00001"
"IAmAString-00023"
What would be a quick'n'easy way to iterate from IAmAString-0001 to IAmAString-00023 by moving up the index of just the numbers on the end?
The problem is a bit more general than that, for example the string I could be dealing could be of any format but the last bunch of chars will always be numbers, so something like Super_Confusing-String#w00t0003 and in that case the last 0003 would be what I'd use to iterate through.
Any ideas?
You can use char.IsDigit:
static void Main(string[] args)
{
var s = "IAmAString-00001";
int index = -1;
for (int i = 0; i < s.Length; i++)
{
if (char.IsDigit(s[i]))
{
index = i;
break;
}
}
if (index == -1)
Console.WriteLine("digits not found");
else
Console.WriteLine("digits: {0}", s.Substring(index));
}
which produces this output:
digits: 00001
string.Format and a for loop should do what you want.
for(int i = 0; i <=23; i++)
{
string.Format("IAmAString-{0:D4}",i);
}
or something close to that (not sitting in front of a compiler).
string start = "IAmAString-00001";
string end = "IAmAString-00023";
// match constant part and ending digits
var matchstart = Regex.Match(start,#"^(.*?)(\d+)$");
int numberstart = int.Parse(matchstart.Groups[2].Value);
var matchend = Regex.Match(end,#"^(.*?)(\d+)$");
int numberend = int.Parse(matchend.Groups[2].Value);
// constant parts must be the same
if (matchstart.Groups[1].Value != matchend.Groups[1].Value)
throw new ArgumentException("");
// create a format string with same number of digits as original
string format = new string('0', matchstart.Groups[2].Length);
for (int ii = numberstart; ii <= numberend; ++ii)
Console.WriteLine(matchstart.Groups[1].Value + ii.ToString(format));
You could use a Regex:
var match=Regex.Match("Super_Confusing-String#w00t0003",#"(?<=(^.*\D)|^)\d+$");
if(match.Success)
{
var val=int.Parse(match.Value);
Console.WriteLine(val);
}
To answer more specifically, you could use named groups to extract what you need:
var match=Regex.Match(
"Super_Confusing-String#w00t0003",
#"(?<prefix>(^.*\D)|^)(?<digits>\d+)$");
if(match.Success)
{
var prefix=match.Groups["prefix"].Value;
Console.WriteLine(prefix);
var val=int.Parse(match.Groups["digits"].Value);
Console.WriteLine(val);
}
If you can assume that the last 5 characters are the number then:
string prefix = "myprefix-";
for (int i=1; i <=23; i++)
{
Console.WriteLine(myPrefix+i.ToString("D5"));
}
This function will find the trailing number.
private int FindTrailingNumber(string str)
{
string numString = "";
int numTest;
for (int i = str.Length - 1; i > 0; i--)
{
char c = str[i];
if (int.TryParse(c.ToString(), out numTest))
{
numString = c + numString;
}
}
return int.Parse(numString);
}
Assuming all your base strings are the same, this would iterate between strings.
string s1 = "asdf123";
string s2 = "asdf127";
int num1 = FindTrailingNumber(s1);
int num2 = FindTrailingNumber(s2);
string strBase = s1.Replace(num1.ToString(), "");
for (int i = num1; i <= num2; i++)
{
Console.WriteLine(strBase + i.ToString());
}
I think it would be better if you do the search from the last (Rick already upvoted you since it was ur logic :-))
static void Main(string[] args)
{
var s = "IAmAString-00001";
int index = -1;
for (int i = s.Length - 1; i >=0; i--)
{
if (!char.IsDigit(s[i]))
{
index = i;
break;
}
}
if (index == -1)
Console.WriteLine("digits not found");
else
Console.WriteLine("digits: {0}", s.Substring(index));
Console.ReadKey();
}
HTH
If the last X numbers are always digits, then:
int x = 5;
string s = "IAmAString-00001";
int num = int.Parse(s.Substring(s.Length - x, x));
Console.WriteLine("Your Number is: {0}", num);
If the last digits can be 3, 4, or 5 in length, then you will need a little more logic:
int x = 0;
string s = "IAmAString-00001";
foreach (char c in s.Reverse())//Use Reverse() so you start with digits only.
{
if(char.IsDigit(c) == false)
break;//If we start hitting non-digit characters, then exit the loop.
++x;
}
int num = int.Parse(s.Substring(s.Length - x, x));
Console.WriteLine("Your Number is: {0}", num);
I'm not good with complicated RegEx. Because of this, I always shy away from it when maximum optimization is unnecessary. The reason for this is RegEx doesn't always parse strings the way you expect it to. If there is and alternate solution that will still run fast then I'd rather go that route as it's easier for me to understand and know that it will work with any combination of strings.
For Example: if you use some of the other solutions presented here with a string like "I2AmAString-000001", then you will get "2000001" as your number instead of "1".
i know how to make a console read two integers but each integer by it self like this
int a = int.Parse(Console.ReadLine());
int b = int.Parse(Console.ReadLine());
if i entered two numbers, i.e (1 2), the value (1 2), cant be parse to integers
what i want is if i entered 1 2 then it will take it as two integers
One option would be to accept a single line of input as a string and then process it.
For example:
//Read line, and split it by whitespace into an array of strings
string[] tokens = Console.ReadLine().Split();
//Parse element 0
int a = int.Parse(tokens[0]);
//Parse element 1
int b = int.Parse(tokens[1]);
One issue with this approach is that it will fail (by throwing an IndexOutOfRangeException/ FormatException) if the user does not enter the text in the expected format. If this is possible, you will have to validate the input.
For example, with regular expressions:
string line = Console.ReadLine();
// If the line consists of a sequence of digits, followed by whitespaces,
// followed by another sequence of digits (doesn't handle overflows)
if(new Regex(#"^\d+\s+\d+$").IsMatch(line))
{
... // Valid: process input
}
else
{
... // Invalid input
}
Alternatively:
Verify that the input splits into exactly 2 strings.
Use int.TryParse to attempt to parse the strings into numbers.
You need something like (no error-checking code)
var ints = Console
.ReadLine()
.Split()
.Select(int.Parse);
This reads a line, splits on whitespace and parses the split strings as integers. Of course in reality you would want to check if the entered strings are in fact valid integers (int.TryParse).
Then you should first store it in a string and then split it using the space as token.
Read the line into a string, split the string, and then parse the elements. A simple version (which needs to have error checking added to it) would be:
string s = Console.ReadLine();
string[] values = s.Split(' ');
int a = int.Parse(values[0]);
int b = int.Parse(values[1]);
string[] values = Console.ReadLine().Split(' ');
int x = int.Parse(values[0]);
int y = int.Parse(values[1]);
in 1 line, thanks to LinQ and regular expression (no type-checking neeeded)
var numbers = from Match number in new Regex(#"\d+").Matches(Console.ReadLine())
select int.Parse(number.Value);
string x;
int m;
int n;
Console.WriteLine("Enter two no's seperated by space: ");
x = Console.ReadLine();
m = Convert.ToInt32(x.Split(' ')[0]);
n = Convert.ToInt32(x.Split(' ')[1]);
Console.WriteLine("" + m + " " + n);
This Should work as per your need!
public static class ConsoleInput
{
public static IEnumerable<int> ReadInts()
{
return SplitInput(Console.ReadLine()).Select(int.Parse);
}
private static IEnumerable<string> SplitInput(string input)
{
return Regex.Split(input, #"\s+")
.Where(x => !string.IsNullOrWhiteSpace(x));
}
}
int a, b;
string line = Console.ReadLine();
string[] numbers= line.Split(' ');
a = int.Parse(numbers[0]);
b = int.Parse(numbers[1]);
Try this:
string numbers= Console.ReadLine();
string[] myNumbers = numbers.Split(' ');
int[] myInts = new int[myNumbers.Length];
for (int i = 0; i<myInts.Length; i++)
{
string myString=myNumbers[i].Trim();
myInts[i] = int.Parse(myString);
}
Hope it helps:)
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace SortInSubSet
{
class Program
{
static int N, K;
static Dictionary<int, int> dicElements = new Dictionary<int, int>();
static void Main(string[] args)
{
while (!ReadNK())
{
Console.WriteLine("***************** PLEASE RETRY*********************");
}
var sortedDict = from entry in dicElements orderby entry.Key/3 , entry.Value ascending select entry.Value;
foreach (int ele in sortedDict)
{
Console.Write(ele.ToString() + " ");
}
Console.ReadKey();
}
static bool ReadNK()
{
dicElements = new Dictionary<int, int>();
Console.WriteLine("Please entere the No. of element 'N' ( Between 2 and 9999) and Subset Size 'K' Separated by space.");
string[] NK = Console.ReadLine().Split();
if (NK.Length != 2)
{
Console.WriteLine("Please enter N and K values correctly.");
return false;
}
if (int.TryParse(NK[0], out N))
{
if (N < 2 || N > 9999)
{
Console.WriteLine("Value of 'N' Should be Between 2 and 9999.");
return false;
}
}
else
{
Console.WriteLine("Invalid number: Value of 'N' Should be greater than 1 and lessthan 10000.");
return false;
}
if (int.TryParse(NK[1], out K))
{
Console.WriteLine("Enter all elements Separated by space.");
string[] kElements = Console.ReadLine().Split();
for (int i = 0; i < kElements.Length; i++)
{
int ele;
if (int.TryParse(kElements[i], out ele))
{
if (ele < -99999 || ele > 99999)
{
Console.WriteLine("Invalid Range( " + kElements[i] + "): Element value should be Between -99999 and 99999.");
return false;
}
dicElements.Add(i, ele);
}
else
{
Console.WriteLine("Invalid number( " + kElements[i] + "): Element value should be Between -99999 and 99999.");
return false;
}
}
}
else
{
Console.WriteLine(" Invalid number ,Value of 'K'.");
return false;
}
return true;
}
}
}
I have a much simpler solution, use a switch statement and write a message for the user in each case, using the Console.write() starting with a ("\n").
Here's an example of filling out an array with a for loop while taking user input. * Note: that you don't need to write a for loop for this to work*
Try this example with an integer array called arrayOfNumbers[] and a temp integer variable. Run this code in a separate console application and Watch how you can take user input on the same line!
int temp=0;
int[] arrayOfNumbers = new int[5];
for (int i = 0; i < arrayOfNumbers.Length; i++)
{
switch (i + 1)
{
case 1:
Console.Write("\nEnter First number: ");
//notice the "\n" at the start of the string
break;
case 2:
Console.Write("\nEnter Second number: ");
break;
case 3:
Console.Write("\nEnter Third number: ");
break;
case 4:
Console.Write("\nEnter Fourth number: ");
break;
case 5:
Console.Write("\nEnter Fifth number: ");
break;
} // end of switch
temp = Int32.Parse(Console.ReadLine()); // convert
arrayOfNumbers[i] = temp; // filling the array
}// end of for loop
The magic trick here is that you're fooling the console application, the secret is that you're taking user input on the same line you're writing your prompt message on. (message=>"Enter First Number: ")
This makes user input look like is being inserted on the same line. I admit it's a bit primitive but it does what you need without having to waste your time with complicated code for a such a simple task.