Easy way to read integers from a file

I am trying to read in a file, which is essentially a list of integers separated by a line. Obviously, file input can never be trusted, so I need to filter out non-integer numbers.

  • 1
  • 2
  • 3
  • 4

I know that the as operator usually converts if it can, and then sets it to null, however, since int not null, it is not. I thought that maybe I could pounce on the Nullable<int> . I never delved into this, I thought that maybe I could do:

 var lines = File.ReadAllLines(""); var numbers = lines.Select(line => line as int?).Where(i => i != null); 

I know that I could potentially get around this by doing:

 var numbers = lines.Select(line => { int iReturn = 0; if (int.TryParse(line, out iReturn )) return iReturn; else return null; }).Where(i => i != null); 

I could also do this as an extension method.

I was just looking for a neat, concise way to make the cast in a statement, and also to understand why my code is invalid.

+4
source share
6 answers

I always use this simple extension method:

 public static int? TryGetInt(this string item) { int i; bool success = int.TryParse(item, out i); return success ? (int?)i : (int?)null; } 

Then itโ€™s easy:

  var numbers = lines.Select(line => line.TryGetInt()) .Where(i => i.HasValue) .Select(i => i.Value); 

You can also use int.TryParse without an extension, but this is undocumented, therefore, it may stop working in the future:

 int i = 0; var numbers = lines.Where(line => int.TryParse(line, out i)) .Select(line => i); 

Edit

"also understands why my code is invalid"

corresponding code:

 if (int.TryParse(line, out iReturn )) return iReturn; else return null; 

It will work if you replace

 else return null; 

with

 else return (int?)null; 

because you return int , but null implicitly converted to int .

+3
source

There is no short way to do this, because here you do not need to make a throw (you cannot throw) - you need to convert from one type to another. The types of courses are int and string (so they arenโ€™t quite โ€œanyโ€ types), but, as in the general case, any conversion between unrelated types cannot be done โ€œexactly the sameโ€.

+1
source

Nope. C # is intentionally cautious about changing strings in numbers.

You can make the code shorter (no more than null) using the foreach loop

 var numbers = new List<int>(); foreach(string line in lines) { int n; if (int.TryParse(line, out n)) numbers.Add(n); } 
0
source

You can create and extend a method.

 public static int? ToInt(this string s, int default){ ... } 

and use it in LINQ:

 var lines = File.ReadAllLines(path); var numbers = lines.Select(line => line.ToInt()) .Where(i => i != null); 
0
source

If I understand you correctly, and you just want to filter non-integer strings, maybe regex is an option?

 var lines = File.ReadAllLines(""); var numbers = lines.Where(i => Regex.IsMatch(i, "[0-9]+")); 
0
source

Here is the best I came up with:

Use this extension method:

 public static class Int32Extensions { public static int? ParseOrDefault(this string text) { int iReturn = 0; if (int.TryParse(text, out iReturn)) { return iReturn; } return null; } } 

Like this:

 var query = lines.Select(x => x.ParseOrDefault()).Where(x => x.HasValue); 
0
source

All Articles