Reading .txt file into an array - c#

I need to be able to read a text file into an array instead of inputting all the values myself.
The text file reads as:
8.7
9.3
7.9
6.4
9.6
8.0
8.8
9.1
7.7
9.9
5.8
6.9
The main purpose of the program is to read scores from a data file, store them in an array, and calculate the highest, lowest, total and average of the 12 scores.
The text file is stored in the Debug folder of the project.
This is what I've done so far:
Console.WriteLine("Numbers in the list: " + scores.Length);
//highest number
double high = scores[0];
for (int index = 1; index < scores.Length; index++)
{
if (scores[index] > high)
{
high = scores[index];
}
}
Console.WriteLine("Highest number = " + high);
//lowest number
double low = scores[0];
for (int index = 1; index < scores.Length; index++)
{
if (scores[index] < low)
{
low = scores[index];
}
}
Console.WriteLine("lowest number = " + low);
//average of the scores
double total = 0;
double average = 0;
for (int index = 0; index < scores.Length; index++)
{
total = total + scores[index];
}
average = (double)total / scores.Length;
Console.WriteLine("Total = " + total);
Console.WriteLine("Average = " + average.ToString("N2"));
Console.ReadKey();
}
}
}

You have no code in place for reading a file, or writing a file so that will be your problem. I suggest you start with looking at: StreamReader Class (MSDN).
Then you will probably want to look at the following: String.Split Method (MSDN)
To make the program a bit more dynamic you possible want to consider looking at this:
Application.ExecutablePath Property (MSDN)
Enviroment.GetFolderPath Method (MSDN) (This allows you to store data in better locations)
^^^^Original Response above^^^^^
Another option you could consider is described in a lot of detail here:
Working with Files - Code Project Article

You can use File.ReadLines method to read the lines lazily (means doesn't load all the lines to memory at once) from your file and Select method to take each line and parse it to double:
var values = File.ReadLines("path")
.Select(line => double.Parse(line))
.ToArray();
Then you can use Max,Min,Average methods from LINQ to get highest,lowest number and the average.

All of this can be writen easier :
using System;
using System.IO;
using System.Linq;
String path = #"MyFolder\myfile.txt"; // path for your file
// read the file
String[] lines = File.ReadAllLines(path);
// convert data in Doubles
Double[] data = Array.ConvertAll(lines, Double.Parse);
// use Linq to get what you want (min, max, total, average, ...)
Double low = data.Min();
Double high = data.Max();
Double total = data.Sum();
Double average = data.Average();

var scores = File.ReadAllLines("scores.txt").Select(x => Double.Parse(x)).ToArray();

var numbers = File.ReadAllLines(#"C:\numbers.txt")
.Select(n => double.Parse(n));
var max = numbers.Max();
var min = numbers.Min();
var sum = numbers.Sum();
var avg = numbers.Average();

Related

Using dictionary for sum of values from a text file from multiple rows and columns

I have text data in format of:
OrderID:100,ItemID:1,Price:1000 //Row1
OrderID:101,ItemID:2,Price:200 //Row2
OrderID:102,ItemID:3,Price:100 //Row3
I need the Totalitems:3 and totalPrice:1300 and I don't know which way to get an output for this problem using Indexof to access or something else
Any help is appreciated.
One way is to first read all the lines from the file with File.ReadAllLines(fileName). Then you can loop through the lines and parse out and aggregate the information you need.
var lines = File.ReadAllLines(fileName);
int totalItems = 0;
decimal totalPrice = 0;
foreach (var line in lines)
{
var columns = line.Split(',');
var priceColumn = columns[2];
var price = decimal.Parse(priceColumn.Split(':')[1]);
totalItems++;
totalPrice += price;
}
Console.WriteLine($"Total items: {totalItems}");
Console.WriteLine($"Total price: {totalPrice}");
For more complex CSV files or more advanced features, you can look at CsvHelper, which has worked well for me.
// parse the price
const string sep = ",Price:";
// initial tuple for sum&count, aka "seed"
(decimal sum, int count) = (0,0);
var lines = File.ReadAllLines(someCsvFilePath);
var result = lines.Aggregate((sum, count),
(curr, line) => line?.IndexOf(sep) is {} pos and > -1
&& decimal.TryParse(line.Substring(pos + sep.Length), out var prc)
? (curr.sum + prc, curr.count + 1) : curr);
Console.WriteLine("Sum: {0:N0}, TotalItems: {1:N0}", result.sum, result.count);

Iteration issues using Linear Search

In my code I have to run through some files with a load of numbers in and at some point need the user to input a number to see if it is in the file or not , if it is in the file then the returning output should be the positioning of where in the file. If it is not in the list then I need to return the closest value to their input. Eg 669 is in the list however 668 is not. My code is as follows for a function to find the nearest value:
static int nearest(int close_num, int[] a)
{
int result = -1;
long smallestDelta = long.MaxValue;
foreach (int bob in a)
{
long delta = (bob > close_num) ? (bob - close_num) : (close_num - bob);
if (delta < smallestDelta)
{
smallestDelta = delta;
result = bob;
}
}
return result;
Then the linear search and the rest is as follows :
Console.WriteLine("Enter a number to find out if is in the selected Net File: ");
int i3 = Convert.ToInt32(Console.ReadLine());
for (int i = 0; i < a.Length; i++)//looping through array
{
if (a[i] == i3)//checking to see the value is found in the array
{
Console.WriteLine("Value found and the position of it in the selected Net File is: " + i, a[i]);
break;
}
else
{
int found = nearest(i3, a);
Console.WriteLine("Cannot find this number in the Net File however here the closest number to that: " + found);
However these are my outputs:[Output 1 : Entering a value that is the file , for some reason prints the else call 3x before , if I remove the break in the code it just breaks. 1
Output 2: Prints whilst running through the whole list of values
how can I fix these formatting issues bc the code is doing what I need it to , just not in a way it should.
Thanks

c# string concat to get another variable

Good day. I would like to ask if it is possible to concatenate 2 strings to get another variable.
Lets say I have this code:
string num1 = "abcdefgh";
string num2 = "ijklmnop";
int numLength = 0;
And I want to get the value of both num1 and num2 using a forloop
for(int i =1; i<= 2; i++)
{
numLength = ("num" + i).Length + numLength;
}
Console.WriteLine("Length is {0}", numLength);
I want it to output
Length is 16
I did the above code but it actually gives me different value.
Edit1: (P.S. I will be using more than 10 variables, I just indicated 2 of it to make it simple)
Edit2: Yes, yes. I want ("num"+i).Length to give me num1.Legnth + num2.Length.
First way:
I suggest you to add all of your strings into the List and then get the total length with Sum method.
List<string> allStrings = new List<string>();
allStrings.Add(num1);
allStrings.Add(num2);
...
allStrings.Add(num10);
var totalLength = allStrings.Sum(x => x.Length);
Second way
Or if you want to calculate total length with for loop:
int totalLength = 0;
for (int i = 0; i < allStrings.Count; i++)
{
totalLength = totalLength + allStrings[i].Length;
}
Third way
If you don't want to use List, then you can use String.Concat and then Length property.
var totalLength = String.Concat(num1, num2).Length;
The result is 16 in your case.
Edit:
In my opinion you think that, ("num" + i).Length will give you num1.Length and num2.Length. This is wrong.
Lets say we have some strings and we want the total length for all this strings.
In this case you need to store all strings in an array, so you can counter them and use indexes.
and after that a simple for (or foreach) loop can solve the problem:
string[] texts = new string[20]; //You can use any number u need, but in my code I wrote 20.
texts[0] = "sample text 1";
texts[1] = "sample text 2";
// add your strings ...
int totalLenght = 0;
foreach (string t in texts)
{
totalLenght += t.Length;
}
Console.WriteLine("Length is {0}", totalLenght);
If you need a variable with unlimited size, use List<T>
here is example:
List<string> texts = new List<string>();
texts.Add("sample text 1");
texts.Add("sample text 2");
// add your strings ....
int totalLenght = 0;
for (int i = 0; i < texts.Count; i++)
{
totalLenght += texts[i].Length;
}
Console.WriteLine("Length is {0}", totalLenght);

Average of Strings With 2 Decimal Points

Using C#, I have 5 strings that are reading data from a temperature sensor on an Arduino board:
string currentTemp1 = serialPort1.ReadLine();
Thread.Sleep(1000);
string currentTemp2 = serialPort1.ReadLine();
Thread.Sleep(1000);..... and so on.
This is returning the values into the strings such as: 19.45, 19.45, 19.50, 19.45, 19.50.
I've tried a bit of research into trying to get the average, but am having problems working out how to convert the strings with the 2 decimal places into an Integer, and then getting the average.
Can someone please point me in the right direction.
The problem is that you don't want to parse the strings into integers. You should use float/double/decimal instead:
var temp1 = float.Parse(currentTemp1);
var temp2 = float.Parse(currentTemp2);
var average = (temp1 + temp2) / 2;
Or, you could use a loop if there's a variable number of integers:
var temps = currentTemp1.Split(", ");
float total;
foreach (var t in temps)
{
total += float.Parse(t);
}
var average = total / temps.Length;

Displaying bandwidth speed in a user-friendly format

I'm looking for a string conversion method that will receive an input of KB/s and converts it to the easiest readable format possible.
e.g. 1500 b/s = 1.46 Kb/s
e.g. 1500 Kb/s = 1.46 Mb/s
e.g. 1500 Mb/s = 1.46 Gb/s
Thanks
Try this:
var ordinals = new [] {"","K","M","G","T","P","E"};
long bandwidth = GetTheBandwidthInBitsPerSec();
decimal rate = (decimal)bandwidth;
var ordinal = 0;
while(rate > 1024)
{
rate /= 1024;
ordinal++;
}
output.Write(String.Format("Bandwidth: {0} {1}b/s",
Math.Round(rate, 2, MidpointRounding.AwayFromZero),
ordinals[ordinal]));
The ordinals (prefixes) available here are Kilo-, Mega-, Giga-, Tera-, Peta-, Exa-. If you really think your program will be around long enough to see Zettabit and Yottabit network bandwidths, by all means throw the Z and Y prefix initials into the array.
To convert from one formatted string to the other, split on spaces, look at the term that will be the number, and then search the term immediately following for one of the prefixes. Find the index of the ordinal in the array, add 1, and multiply by 1024 that many times to get to bits per second:
var bwString= GetBandwidthAsFormattedString(); //returns "Bandwidth: 1056 Kb/s";
var parts = String.Split(bwString, " ");
var number = decimal.Parse(parts[1]);
var ordinalChar = parts[2].First().ToString();
ordinalChar = ordinalChar = "b" ? "" : ordinalChar;
var ordinal = ordinals.IndexOf(ordinalChar)
... //previous code, substituting the definition of ordinal
I made this code in about 30 secondes, so there is no validation, but I think it does what you want
string vInput = "1500 Kb/s";
string[] tSize = new string[] { "b/s", "Kb/s", "Mb/s", "Gb/s" };
string[] tSplit = vInput.Split(new string[] {" "}, StringSplitOptions.RemoveEmptyEntries);
double vSpeed = Double.Parse(tSplit[0]) / 1024.0;
vSpeed = Math.Round(vSpeed, 2);
int i = 0;
for(i = 0; i < tSize.Length;++i)
{
if(tSplit[1].StartsWith(tSize[i]))
{
break;
}
}
string vOutput = vSpeed.ToString() + " " + tSize[i+1];

Categories

Resources