I am working on a program that read the file with car model and fuel consumption.
In file I have cars like A|12.45, where A stand for model and number stands for fuel consumption per 100Km. Every car is in it's own line.
File looks like that:
A|8.11
B|14.38
C|13.05
Here we can see that B has highest consumption but when I run that program in console it shows up as 1438 L without dot in the middle. How can I fix this?
I have a code that looks like this:
static void Main(string[] args)
{
StreamReader readF = File.OpenText(@"D:\CarList.txt");
string line = readF.ReadLine();
double highest = 0;
double lowest = 300;
string nameHighest= "";
string nameLowest= "";
while (line != null)
{
string[] temp = line.Split('|');
if (Convert.ToDouble(temp[1]) > highest)
{
highest= Convert.ToDouble(temp[1]);
nameHighest = temp[0];
}
if (Convert.ToDouble(temp[1]) < lowest)
{
lowest = Convert.ToDouble(temp[1]);
nameLowest = temp[0];
}
line = readF.ReadLine();
}
readF.Close();
Console.WriteLine("Highest consumption: " + nameHighest + ". It consumes " + highest + " L per 100Km.");
Console.WriteLine("Lowest consumption " + nameLowest + ". It consumes " + lowest + " L per 100Km");
Console.ReadKey();
}
Thanks!
I strongly suspect this is because the default culture on your machine is one that uses ,
instead of .
for a decimal separator. You can use double.Parse
and specify CultureInfo.InvariantCulture
to parse it using the invariant culture which does use .
for the separator.
I would actually rewrite your code in several steps.
Step 1: use double.Parse
, and only do so once per line - likewise extract temp[0]
once per line.
Step 2: use double.NegativeInfinity
as the initial "highest" and double.PositiveInfinity
as the initial "lowest", so that any finite entry will register.
Step 3: use a format string at the end. With C# 6 we can use string interpolation, but at least we can make it simpler than it is before then.
Step 4: use File.ReadLines
instead of reading them "manually"
At this point we have:
using System;
using System.Globalization;
using System.IO;
class Test
{
static void Main(string[] args)
{
double highest = double.NegativeInfinity;
double lowest = double.PositiveInfinity;
string nameHighest= "";
string nameLowest= "";
foreach (var line in File.ReadLines("test.txt"))
{
string[] temp = line.Split('|');
string name = temp[0];
double consumption = double.Parse(
temp[1],
CultureInfo.InvariantCulture);
if (consumption > highest)
{
highest = consumption;
nameHighest = name;
}
if (consumption < lowest)
{
lowest = consumption;
nameLowest = name;
}
}
Console.WriteLine(
"Highest consumption: {0}. It conumes {1}L per 100km",
nameHighest, highest);
Console.WriteLine(
"Lowest consumption: {0}. It conumes {1}L per 100km",
nameLowest, lowest);
}
}
Step 5: use LINQ to separate the reading and parsing of the data from the using it - although I'm storing everything in a list so we can go through it twice in a minute...
using System;
using System.Globalization;
using System.IO;
using System.Linq;
class Test
{
static void Main(string[] args)
{
var cars = File.ReadLines("test.txt")
.Select(line => line.Split('|'))
.Select(bits => new { Name = bits[0], Consumption = double.Parse(bits[1]) })
.ToList();
if (cars.Count == 0)
{
Console.WriteLine("No cars!");
return;
}
var highest = cars[0];
var lowest = cars[0];
foreach (var car in cars.Skip(1))
{
if (car.Consumption > highest.Consumption)
{
highest = car;
}
if (car.Consumption < lowest.Consumption)
{
lowest = car;
}
}
Console.WriteLine(
"Highest consumption: {0}. It consumes {1}L per 100km",
highest.Name, highest.Consumption);
Console.WriteLine(
"Lowest consumption: {0}. It consumes {1}L per 100km",
lowest.Name, lowest.Consumption);
}
}
Step 6: Use MoreLINQ's MinBy
and MaxBy
to make it really simple:
using MoreLinq;
using System;
using System.Globalization;
using System.IO;
using System.Linq;
class Test
{
static void Main(string[] args)
{
var cars = File.ReadLines("test.txt")
.Select(line => line.Split('|'))
.Select(bits => new { Name = bits[0], Consumption = double.Parse(bits[1]) })
.ToList();
if (cars.Count == 0)
{
Console.WriteLine("No cars!");
return;
}
var highest = cars.MaxBy(c => c.Consumption);
var lowest = cars.MinBy(c => c.Consumption);
Console.WriteLine(
"Highest consumption: {0}. It consumes {1}L per 100km",
highest.Name, highest.Consumption);
Console.WriteLine(
"Lowest consumption: {0}. It consumes {1}L per 100km",
lowest.Name, lowest.Consumption);
}
}
See more on this question at Stackoverflow