Convert ReadLine() to int - c#

I have a file which contains on each line a value from {-1, 0, 1, 2, 3}. It looks like this:
I want to put all this values in an array of type int like this:
int[] linesValue = new int[NUMBER_OF_LINES];
int i;
for (i = 0; i < NUMBER_OF_LINES; i++)
{
string tmpVal = reader.ReadLine();
linesValue[i] = Convert.ToInt32(tmpVal);
}
"NUMBER_OF_LINES" is a private int and "reader" is a StreamReader.
When I run the code it gives me the error: "Input string was not in the correct format"
I tried reader.ReadLine().ToString() but it still doesn't work.
I would really appreciate if you guys can help me with this problem.

You are getting the last line or line breaks as an empty string in your string and that can't be converted into int, hence the exception. Just add a check for string.IsNullOrWhiteSpace like:
{
string tmpVal = reader.ReadLine();
if(!string.IsNullOrWhiteSpace(tmpVal))
{
linesValue[i] = Convert.ToInt32(tmpVal);
}
}
Also make sure that you are maintaining your index with this check, hence you may end up with empty entries in your array due to index increment.
You can also use File.ReadLines and parse each line to int array like:
int[] array = File.ReadLines("filePath")
.Where(r => !string.IsNullOrWhiteSpace((r)))
.Select(r => int.Parse((r)))
.ToArray();
Look for using int.TryParse method. TryParse group of methods doesn't raise an exception if parsing fails. They return a bool indicating if parsing was successful or not, and the parsed value is provided in the out parameter.

Related

how to convert a String list into a String array then converting it into an int array then counting the total sum of the numbers in the array?

So I am so fresh into the world of programming, starting new, I decided to start messing around in C# to create simple apps from ideas that come to mind, with this little app, I'm trying to have multiple TextBoxes named d1,d2,d3,d4,etc... the user inserts numbers into the textboxes then clicks button1, which begins the process in the code below creating a new list which contains all of the values of the textboxes and then the list is converted to an array and the array is then converted into an int array, etc....
BUT, when starting the application and I add values to the textboxes and then click button1, it shows 2 error like shows in the //gray code line below
Please help.
private void button1_Click(object sender, EventArgs e)
{
List<string> dodo = new List<string>();
dodo.Add(d1.Text); dodo.Add(d2.Text); dodo.Add(d3.Text); dodo.Add(d4.Text); dodo.Add(d5.Text);
dodo.Add(d6.Text); dodo.Add(d7.Text); dodo.Add(d8.Text); dodo.Add(d9.Text); dodo.Add(d10.Text);
dodo.Add(d11.Text); dodo.Add(d12.Text); dodo.Add(d13.Text); dodo.Add(d14.Text); dodo.Add(d15.Text);
dodo.Add(d16.Text); dodo.Add(d17.Text); dodo.Add(d18.Text); dodo.Add(d19.Text); dodo.Add(d20.Text);
foreach(string numb in dodo)
{
if (numb == "")
numb = "0"; //numb word has a red underline
}
string[] terms = dodo.ToArray();
int[] valv = {};
int x = 0;
for(int i=0;i<=19;i++)
{
valv[i] = int.Parse(terms[i]); //the ; in the end has a red underline and shows "FormatException was unhandled" error
i++;
x = x + valv[i];
}
string myString;
myString = x.ToString();
Result1.Text = myString;
}
you can't change the iteration variable which is numb in your case. Please change in the List container instead
List<string> dodo = new List<string>();
dodo.Add(d1.Text); dodo.Add(d2.Text); dodo.Add(d3.Text); dodo.Add(d4.Text); dodo.Add(d5.Text);
dodo.Add(d6.Text); dodo.Add(d7.Text); dodo.Add(d8.Text); dodo.Add(d9.Text); dodo.Add(d10.Text);
dodo.Add(d11.Text); dodo.Add(d12.Text); dodo.Add(d13.Text); dodo.Add(d14.Text); dodo.Add(d15.Text);
dodo.Add(d16.Text); dodo.Add(d17.Text); dodo.Add(d18.Text); dodo.Add(d19.Text); dodo.Add(d20.Text);
int k = 0;
foreach (string numb in dodo)
{
if (numb == "")
{
//numb = "0"; //numb word has a red underline
dodo[k] = "0";
}
k++;
}
Now your code on parsing into integer won't give any runtime error.
The first line "tells" you that you are not able to assign a new value to the variable which is used as a foreach iteration variable.
The second line, "tells" you that you have string value which is not able to be parsed correctly (e.g. user put string which is not a number). To avoid this you can use Int32.TryParse method instead, which will safely try to parse the given string.
The best and easiest way to achieve what you need is using LINQ methods, here is the example based on few things/assumptions:
Since you are converting empty strings into zeros, you could simply skip those entries from counting
To avoid FormatException, you should use TryParse method instead. Since TryParse method will safely parse the given string, you don't even have to filter empty strings at all (they will be skipped). However, I deliberately left filtering part, to get you a better overview of a solution.
You can use list initializer to make list initialization more readable
Solution:
List<string> dodo = new List<string>()
{
d1.Text, d2.Text //...others
};
int sum = dodo
.Where(item => !String.IsNullOrEmpty(item))
.Sum(item =>
{
if (Int32.TryParse(item, out int parsedItem))
{
return parsedItem;
}
return 0;
});
You can get more familiar with LINQ and used methods on following link

why does parse function return o?

I am new to c# programming and I recently bumped into one problem which looks pretty basic.I store the string value like SV_1 in the variable lastServiceNo and split it using Split function and the result is stored in string array called index.Basically index[1] has some numeric value bt as string. now I want to convert string into int. In the following code , it behaves as expected until parse function is encountered.I could not understand why does this parse function returning 0 as index[1] has some numeric value in it. Can somebody point the problem please??
public string GenerateServiceNo() {
DataAccessLayer.DataAccessLayer dlObj= new DataAccessLayer.DataAccessLayer();
string lastServiceNo = dlObj.GetLastServiceNo();
string[] index = lastServiceNo.Split('_');
int lastIndex = int.Parse(index[1]);
return "SV_"+(lastIndex++).ToString();
}
int.Parse(string s) throws an exception if the number is too bug in terms of data size or the string "s" is not in the correct numerical format.
The format that this method accepts is "[ws][sign]number[ws]" where:
[ws] is optional for one or more whitespace(" ")
[sign] is optional for "+" or "-"
Check here for the full reference.
Thus said, I can assure you that if int.Parse(index[1]) returns 0 then that means index[1] equals "[ws][sign]0[ws]" using the transcript above.
However, looking at your code, I can conclude that you're incrementing a local variable after assignment without using its incremented value afterwards. Perhaps you meant that this operation shouldn't be 0?
If that's the case then I believe this is what you're trying to achieve:
public string GenerateServiceNo()
{
DataAccessLayer.DataAccessLayer dlObj= new DataAccessLayer.DataAccessLayer();
string lastServiceNo = dlObj.GetLastServiceNo();
string[] index = lastServiceNo.Split('_');
int lastIndex = int.Parse(index[1]);
return string.Format("SV_{0}", ++lastIndex);
}
Assuming index[1] == "0", this method will now return "SV_1".

Having trouble converting string to int

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.

C# Loop Through An Array

I am completely new to C#. I am trying to loop through a short array, where the string elements in the array are placed at the end of a website search. The code:
int n = 1;
string[] s = {"firstitem","seconditem","thirditem"}
int x = s.Max(); // note, from my research this should return the maximum value in the array, but this is the first error
x = x + 1
while (n < x)
{
System.Diagnostics.Process.Start("www.website.com/" + b[0]);
b[]++; // this also generates an error "identifier expected"
}
My coding, logic or both are wrong. Based on what I've read, I should be able to get the maximum value in an array (as an int), then add to the arrays value while a WHILE loop adds each value in the array at the end of the website (and then stops). Note, that on the first error, I tried coding it differently, like the below:
int x = Convert.ToInt32(s.Max);
However, it generates an overload error. If I'm reading things correctly, MAX should find the maximum value in a sequence.
foreach(var str in s)
{
System.Diagnostics.Process.Start("www.website.com/" + str);
}
You have a collection of strings. The largest string is still a string, not an int. Since s.Max() is a string, and you're assinging it to a variable of type int: int x = s.Max(); the compiler (correctly) informs you that the types do not match. You need to convert that string to an int. Since, looking at your data, they aren't integers, and I see no sensible way of converting those strings into integers, I see no reasonable solution. What integer should "firstitem" be?
If you just want to execute some code for each item in the array then use one of these patterns:
foreach(string item in s)
{
System.Diagnostics.Process.Start("www.website.com/" + item);
}
or
for(int i = 0; i < s.Length; i++)
{
System.Diagnostics.Process.Start("www.website.com/" + s[i]);
}
You're missing a couple of semi-colons
x should presumably be the Length of the array, not the largest value in it
You need to increment x inside of your loop - at the end of it, not outside of it
You should actually be incrementing n, not x
n should be starting at 0, not at 1
Inside the loop you're using b[0] where you probably want to use b[n]
I'm no C++ guru, but I have no idea what b[]++ might mean
As other answers have mentioned, you may want to use a for or foreach instead of a while.
Make an effort to go through some introductory tutorials. Trial and error can be a useful tool, but there's no need to fall back on that when learning the very basics
Following is an image to point out what are the errors of your code:
After the correction, it would be:
int n=1;
string[] s= { "firstitem", "seconditem", "thirditem" };
int x=s.Length;
while(n<x) {
System.Diagnostics.Process.Start("www.website.com/"+s[n]);
n++; // or ++n
}
And we can make it more semantic:
var items=new[] { "firstitem", "seconditem", "thirditem" };
for(int index=1, count=items.Length; index<count; ++index)
Process.Start("www.website.com/"+items[index]);
If the starting order doesn't matter, and we can use foreach instead, and we can use Linq to make the code even simpler:
var list=(new[] { "firstitem", "seconditem", "thirditem" }).ToList();
list.ForEach(item => Process.Start("www.website.com/"+item));
and we might quite often write in another form:
foreach(var item in new[] { "firstitem", "seconditem", "thirditem" })
Process.Start("www.website.com/"+item);
from the sample
var processList = (new string[]{"firstitem","seconditem","thirditem"})
.Select(s => Process.Start("www.website.com/" + s))
.ToList();
and here is a test version that outputs to console
(new string[] { "firstitem", "seconditem", "thirditem" })
.Select(s => { Console.WriteLine(#"www.website.com/" + s); return s; })
.ToList();
note: Select requires a return type and the .ToList() enforces evaluation.

send a String array as parameter to a function

I have a function in a class called Function, like below:
public int SearchedRecords(String [] recs)
{
int counter = 0;
String pat = "-----";
String[] records = recs;
foreach (String line in records)
{
if (line.Contains(pat) == true)
{
counter++;
}
}
return counter;
}
And I am calling this method from my main class this way:
String [] file = File.ReadAllLines("C:/Users.../results.txt");
int counter = Function.SearchedRecords( []file);
But I get an error saying:
;expected
What is wrong?
Another question: The function above is counting from a file all the lines with the pattern ----- in them (even if with more dashes, or if the line has some chars before or after the dashes). Am I right?
It's something like the patterns in Java so maybe there is an other way.
Can you enlighten me?
Remove the [] from your parameter.
e.g.
int counter = Function.SearchedRecords(file);
And yes, your assumption about the behavior of the Contains method is correct - you'll match any line containing five consecutive dashes, regardless of what characters are before or after them.
If you want to parse for exactly five dashes, with nothing before or after them I suggest looking into the RegEx class (regular expressions).
Change
int counter = Function.SearchedRecords( []file);
to
int counter = Function.SearchedRecords(file);
and yes, this will work, for that string.
However Contains is case sensitive, if you were matching on a name, or another string with alphabetic characters, the case would have to be identical to match e.g. line.Contains("Binary Worrier") will not match a string "Hello binary worrier".
Also, reading the entire file into memory is fine if you know that the file will always be small, this method gets less efficient the larger the file.
Better to always use something like System.IO.StreamReader or System.IO.File.ReadLines (available in .Net 4 and later), these allow you to consume the file one line at a time. e.g.
using (var reader = new System.IO.StreamReader("MyFile.txt"))
{
while(!reader.EndOfStream)
{
string line = reader.ReadLine();
if (line.Contains(pattern))
counter++;
}
}
Change it to
int counter = Function.SearchedRecords(file);
Remove '[]' from a method call. Yes, your function seems to count what you want.
First of all you need to create an instance of function class and then run the function. Hope following code helps
Function fb = new Function();
int counter = fb.SearchedRecords(file);
Right now, you are using SearchRecords as an static function of a static class which doesn't require instantiation.
You can do this in a shorter way using LINQ:
int counter = file.Count(line => line.Contains("-----"));

Categories

Resources