I have an assignment where the I gotta figure out a way to make the input read both double and decimal and perform a few operations as new method.
char[] charSeparators = new char[] { ' ' };
Console.Write("Please type few numbers: ");
dynamic[] test = Console.ReadLine().Split(charSeparators, StringSplitOptions.RemoveEmptyEntries).ToArray();
dynamic value = test[0];
for (int i = 1; i < test.Length; i++)
{
if (test[i] < value)
{
value = test[i];
}
}
I figured out to use dynamic as data type, but this throws an exception:
Operator '<' cannot be applied to operands of type 'string' and 'string'
I already made a fallback using a switch where the user selects if it's double or decimal but I thought this was way more simple.
How to stop that dynamic from being read as string ?
Note that the split method always returns an array of strings, so you have to convert it results. The problem isn't the Dynamic.
Example:
char[] charSeparators = new char[] { ' ' };
Console.Write("Please type few numbers: ");
dynamic[] test = Console.ReadLine().Split(charSeparators, StringSplitOptions.RemoveEmptyEntries).ToArray();
double value = double.Parse(test[0]);
for (int i = 1; i < test.Length; i++)
{
if (double.Parse(test[i]) < value)
{
value = double.Parse(test[i]);
}
}
try this:
var value= Convert.ToDecimal( test[0])
or
var value= Convert.ToDouble( test[0])
because test[0] is a string, so when you define it as dynamic, its type binds in run time but makes no difference because its type is clear in compile-time and no need to define it as dynamic.
You are taking the console input which will be a string. In order to turn in into any sort of numeric value you need to parse it.
dynamic[] test = Console.ReadLine().Split(charSeparators, StringSplitOptions.RemoveEmptyEntries).ToArray(); will be a string array, so you'll need to cast it to a decimal or a double.
I'm not sure how you're going to figure out whether it's double of decimal, so why not cast them all to decimal, since that type keeps its precision.
Your current array contains strings. You need to convert them to decimals or doubles
dynamic[] test = Console.ReadLine().Split(charSeparators, StringSplitOptions.RemoveEmptyEntries).ToArray().Select(double.Parse).ToArray();
Related
I am new at programming, I am trying to insert values inside four arrays using one for loop. However I only get the error: (Argument 2 may not be passed with the 'out' keyword. I know that's something wrong around the console readline but I don't what I can do to turn around this situation. That's my code so far:
int size;
do
{
Console.Clear();
Console.Write("What is the size of the array: ");
} while (!int.TryParse(Console.ReadLine(), out size));
string[] name = new string [size];
double[] grade1 = new double [size];
double[] grade2 = new double[size];
double[] avarage = new double [size];
for (int i = 0; i < size; i++)
{
do
{
Console.Write($"Insert the name of student number: {i + 1}: ");
} while (!Convert.ToString(Console.ReadLine(), out name[i]));
do
{
Console.Write($"Insert {i + 1}º grade: ");
} while (!Convert.ToDouble(Console.ReadLine(), out grade1[i]));
}
While int.TryParse returns a bool, Convert.ToString and Convert.ToDouble do not, and unlike other languages, C# won't let you treat other types as bool to shorthand null comparisons. Thus, you generally can't use !value when value is not a bool.
Note that in the case of the second conversion, you're converting a string (console input) to a string, so it's not necessary - just take the string and check for IsNullOrWhitespace (although you'll need multiple line). Thus
do
{
Console.Write($"Insert the name of student number: {i + 1}: ");
name[i] = Console.ReadLine();
} while (string.IsNullOrWhitespace(name[i]));
For the third conversion, you could use double.TryParse instead,
} while(!double.TryParse(Console.ReadLine(), out grade1[i]));
Notably, most of the numerical types in .NET support TryParse methods, and converting a string to a string just to make code look the same is a good example of the YAGNI principle.
I'm trying to convert a string (ex. "0.20055") to its equivalent double.
I already know that for some reason that string does not contain a valid double, but I don't understand why.
I really need to be able to convert this string to a double... Could anyone explain me why it's not a valid double? And how to fix this?
Here is some of my code:
double[] values_in_double = null;
string[] values_in_string = lines[j].Split(',');
for(int x=0; x < numCols; x++)
{
double val;
bool r = double.TryParse(values_in_string[x],out val);
if (!r)
return;
values_in_double[x] = Convert.ToDouble(values_in_string[x]);
}
As you can see I have a string[] of lines, in which a line is like:
0.20055,0.37951,0.39641,2.0472,32.351,0.38825,0.24976,1.3305,1.1389,0.50494
and I split them. But then I need to convert each one to a double value.
The main changes I would make to your code are to
remove the return statement since that will exit our method prematurely
use a List<double> to store your doubles (you don't have to declare a size ahead of time, which is nice because we don't know for sure how many items in the string will successfully convert to a double)
to use the val variable when adding it to the List, since double.TryParse has assigned the value to this variable already.
I also added a check to ensure that the variable numRows is not larger than the string array, because that would cause an exception in our loop:
// Mock values read from file
var input = new StringBuilder();
input.Append("0.20055,0.37951,0.39641,2.0472,32.351,0.38825,0.24976,1.3305,");
input.Append("1.1389,0.50494,0.24976,0.6598,0.1666,0.24976,497.42,0.73378,");
input.Append("2.6349,0.24976,0.14942,43.37,1.2479,0.21402,0.11998,0.47706,");
input.Append("0.50494,0.60411,1.4582,1.7615,5.9443,0.11788,593.27,0.50591,");
input.Append("0.12804,0.66295,0.14942,94.14,3.8772,0.56393,0.21402,1.741,");
input.Append("1.5225,49.394,0.1853,0.11085,2.042,0.051402,0.12804,114.42,");
input.Append("71.05,1.0097,348690,0.12196,0.39718,0.87804,0.37854,0.25792,");
input.Append("2.2437,2.248,0.001924,8.416,5.1372,82.658,4.4158,7.4277");
string[] values_in_string = inputString.ToString().Split(',');
// Declare values_in_double as a List so we don't have to worry about sizing
List<double> values_in_double = new List<double>();
// We will get errors if numCols is larger than our string array, so to be safe,
// set a variable that is the smallest of either numCols or our string array length
var numIterations = Math.Min(numCols, values_in_string.Length);
for (int x = 0; x < numIterations; x++)
{
double val;
// If TryParse succeeds, 'val' will contain the double value, so add it to our List
if (double.TryParse(values_in_string[x], NumberStyles.Any,
System.Globalization.CultureInfo.InvariantCulture, out val))
{
values_in_double.Add(val);
}
}
There is also a much shorter way to write this code. The line basically says: For each item in values_in_string, Where double.TryParse returns true, Select val (the item as a value) And convert all the val items into a List:
string[] values_in_string = inputString.ToString().Split(',');
double val = 0;
List<double> values_in_double = values_in_string
.Where(value => double.TryParse(value, NumberStyles.Any,
System.Globalization.CultureInfo.InvariantCulture, out val))
.Select(v => val)
.ToList();
Try this
Double.TryParse(values_in_string[x], NumberStyles.Any, CultureInfo.InvariantCulture, out val);
change
double[] values_in_double = null;
string[] values_in_string = lines[j].Split(',');
to
string[] values_in_string = lines[j].Split(',');
int arraySize = values_in_string.Length;
double[] values_in_double = new double[arraySize];
as you use
double[] values_in_double = null;
and value cannot be assign to null array
Try changing the line :
double[] values_in_double = null;
into
double[] values_in_double = new double[numCols];
Because otherwise the code you provided wouldn't run since the array is not defined (cannot be null).
The problem you have with that is the culture definition on your PC or server, if the delimitator are ',' the sistem interpret '.' as a char.
Use like this:
double vValue;
string[] vValuesString = vLines[j].Split(',');
double[] vValuesDouble = new double[vValuesString.Length];
for (int x = 0; x < vValuesString.Length; x++)
if (double.TryParse(vValuesString[x], System.Globalization.NumberStyles.Any, System.Globalization.CultureInfo.InvariantCulture, out vValue))
return; 'or use' continue;'or use' vValuesDouble[x] = 0;
else vValuesDouble[x] = vValue;
NOTES:
Instance your 'double[] vValuesDouble = new double[vValuesString.Length];', you can't asing a value to a null array.
When you use a TryParce the out var return with the result of convert string to a double, you don't need to re-convert it again.
Never declare variable in a loop, it get declare and instace every run of loop.
TryParce return a bool value that indicates the result of convert you don't need declare and instance a var, just use it in a if.
Use some protocol to define your variable's name.
Try to resume your code the most posible you can.
I put the entire using System.Globalization, but you can declare the using on top or define your System.Globalization for your entire aplication.
And last, sorry for my english, is not my first languaje.
Best.
In my program I have a treeView. In the section that I am working with, the node's displayNames are numerical integer values, but are displayed as strings. I have come to a point in my program where I need to convert and temporarily store these displayNames in an integer variable. I usually use Regex.Match() to do this with no problem, but in this scenario I am getting the compiler error: Cannot implicitly convert type 'string' to 'int'.
This is my code:
//This is the parent node as you may be able to see below
//The children of this node have DisplayNames that are integers
var node = Data.GetAllChildren(x => x.Children).Distinct().ToList().First(x => x.identify == 'B');
//Get # of children -- if children exist
if (node.Children.Count() > 0)
{
for (int i = 0; i < node.Children.Count(); i++)
{
//Error on this line!!**
IntValue = Regex.Match(node.Children.ElementAt(i).DisplayName.Value, #"\d+").Value;
}
}
*NOTE: DisplayName.Value is a string
To get from string to int, use int.Parse(string), it returns the int represented by the passed string and throws if the input format is incorrect.
int.Parse(node.Children.ElementAt(i).DisplayName.Value)
You can also use int.TryParse if you don't want the throw. in that case you would use:
int parsedValue;
if (int.TryParse(node.Children.ElementAt(i).DisplayName.Value, out parsedValue))
{
///Do whatever with the int
}
The problem is becuase you're casting from Match to int in this call
IntValue = Regex.Match(node.Children.ElementAt(i).DisplayName.Value, #"\d+").Value;
Try something like this:
Match m = Regex.Match(node.Children.ElementAt(i).DisplayName.Value, #"\d+").Value;
int value = m.Matches[0] //You'll have to verify this line, I'm going from memory here.
Hello i have an inputtextfield were i want to put figures for example 100 to have a script loop for 100 times, but im getting an error all the time. When putting a number at the place it does run normal, i'm trying to feed it with a number from the textbox.
for (var i = 0; i < (textBox2.Text); i++)
{
code in here
}
Here's the error : Error 1 Operator '<' cannot be applied to operands of type 'int' and 'string'
What am i doing wrong? Can someone help me??
You give textBox2.Text although it would have number but it has type string and you need integer.
int result = int.Parse(textBox2.Text);
for (var i = 0; i <result ; i++)
{
//Your code
}
Check if the text can be Parsed to an int first and then proceed. Following int.TryParse() method will return true if textBox2.Text.Trim() is an int
int limit;
if( int.TryParse(textBox2.Text.Trim(), out limit))
{
for (var i = 0; i < limit ; i++)
{
//code in here
}
}
The error message is quite clear, you're trying to compare an integer to a string value. That obviously won't work. You need first to cast the value from the textbox to integer type, than you can apply the condition for the for-loop.
Use Int.Parse(txtFirst.Text);
One thing, you seem to be a beginner, I want you to follow naming conventions in coding like txt prepended to the name of textbox, lbl for label and you can find more in your study material...
You need to parse the textBox2.Text String to get an int. For instance:
int x = int.Parse(textBox2.Text);
for (var i = 0; i < x; i++)
As others have mentioned, textbox2.text is a string and must be converted to a #n integer
for (var i = 0; i < int.Parse(textBox2.Text); i++)
{
//code in here
}
However, i wound recommend you use a more appropriate control, such as a numeric Up Down:
for (var i = 0; i < Convert.ToInt32(numericUpDown1.Value); i++)
{
code in here
}
The value in textBox2.Text is of type string , you need to cast it to int.
This is done by cint() function
cint(textBox2.Text)
or Parse() method
Int32.Parse(textBox2.Text);
THe above two methods will work if you are sure the input string is valid that contains something like "123" rather than "absjsdfd".
for (var i = 0; i < Int32.Parse(textBox2.Text); i++)
{
//your code in here
}
To avoid throwing exception if invalid input is entered in textbox use a more robust function Integer.TryParse()
int limit;
bool valid = int.TryParse(textbox2.Text, out limit);
if(valid)
for (var i = 0; i < limit; i++)
{
//your code in here
}
You need to use the Int32.Parse() method to convert the text in the textbox to an integer. The Text field is only an string and the compiler cannot figure out what you are trying to do.
how to convert a string array to nullable integer array.
Well, the two aspects are:
How do you convert an array from one type to another?
How do you convert a string to a nullable int?
The first is simple - you can use Array.ConvertAll, passing in an Converter delegate. There's the LINQ way as well (x.Select(...).ToArray()), but that's slightly less efficient if you know you've got an array to start with and you want an array out of the other end 1.
The string to int? is probably best done in a method. You can do it in an anonymous function, but in this particular case I'd use a separate method. I rarely like to have to declare variables in an anonymous function.
public static int? TryParseInt32(string text)
{
int value;
return int.TryParse(text, out value) ? value : (int?) null;
}
To answer the comment, yes you need the cast 2.
or without the conditional:
public static int? TryParseInt32(string text)
{
int value;
if (int.TryParse(text, out value))
{
return value;
}
else
{
return null;
}
}
Put them together like this:
string[] x = {"15", "10", "hello", "5" };
int?[] y = Array.ConvertAll(x, TryParseInt32);
1 Array.ConvertAll is more efficient than x.Select().ToArray() because it has more information. It can create the final array immediately - no resizing is ever required. Calling Enumerable.ToArray() (with the result of Select()) doesn't have the same information, so it effectively has to add the results to a List<T> (potentially resizing several times along the way) and then usually resize at the end as well. (It doesn't actually use List<T> but the concepts are the same.) It's definitely worth knowing about the Select/ToArray solution, but I don't think it's actually any more readable than ConvertAll in this case, so you might as well use the more efficient form.
2 The reason you need the cast in the conditional is because the compiler doesn't know what type of "null" you really mean - but it knows it can't convert from null to an int. The type of the conditional expression has to be either the type of the second operand or the type of the third operand, and the other one has to be implicitly convertibly. By forcing the third operand to be of type int? here everything is fine - because you can implicitly convert from int to int?. Note that the compiler doesn't take the way you're using the expression to try to work out the type. Another alternative is to use new int?() instead of null.
By parsing and using Linq:
string[] input = { "1", "3", "x" }
var result = input.Select(
s => { int i; return (int.TryParse(s, out i)) ? i : (int?) null; }).ToArray();
… but I grant that this is a bit cryptic. I wouldn’t use a lambda expression here. For clarity, this should belong to a proper function ParseNullableInt. Then you can call it like this:
var result = input.Select(ParseNullableInt).ToArray();
Edit: I removed the null/empty check because TryParse properly handles those cases by returning false.
string[] stringArray = ...;
int?[] nullableIntArray = Array.ConvertAll(stringArray,
s =>
{
int value;
if (!int.TryParse(s, out value))
return default(int?);
return (int?)value;
});
One option would be this (I'm presuming that you want nulls for the values that were not integer values):
public static class StringArrayExtension
{
public static int?[] ToNullableIntArray(this string[] array)
{
int?[] result = new int?[array.Length];
for (int index = 0; index < array.Length; index++)
{
string sourceValue = array[index];
int destinationValue;
if (int.TryParse(sourceValue, out destinationValue))
{
result[index] = destinationValue;
}
else
{
result[index] = null;
}
}
return result;
}
}
usage:
string[] source = { "hello", "1", "3.1415", "20", "foo" };
int?[] dest = source.ToNullableIntArray();
You need to use int.TryParse:
string[] s = { "123", "a", "45" };
int?[] result = new int?[s.Length];
for (int i = 0; i < s.Length; ++i)
{
int a;
if (int.TryParse(s[i], out a))
result[i] = a;
}
List<int?> ints = new List<int?>();
foreach (string str in strs)
{
int val;
if (int.TryParse(str, out val))
{
ints.Add(val);
}
else { ints.Add(null); }
}
return ints.ToArray();
An integer array can not be null. In fact every element in Integer Array will have "0" by default.
Regarding Conversion
Create an Integer array of the same length or an arraylist
int [] _arr=new int[strArray.length];
for(int i=0;i<strArray.length;i++]
{
if(String.IsNullOrEmpty(strArray[i]))
{
_arr[i]=0;
}
else
{
_arr[i]=int.Parse(strArray[i]);
}
}