The Input File
We have to read an input file line by line. This is the file that will be placed on the desktop. The name of the file is "record.txt".
// file called records.txt // this file is placed on the desktop // directory of the user's computer CHD01,23567 PTA02,7879 FZR03,542121 MHL11,3232 JAL22,43432 ASR05,90896
Each record contains two data items separated by a comma. The first part is of exactly 5 characters and contains a supplier code. The second part is a numeric amount.
Video Explanation (see it happen!)
Please watch the following youtube video:
The Desired Output File
We have to process the file and produce an output file called "report.txt". This file contains the same records but sorted in ascending order of the bill amount. The sum total of all the bills appears at the end.
// report.txt
MHL11,3232
PTA02,7879
CHD01,23567
JAL22,43432
ASR05,90896
FZR03,542121
===============
Total Amount 711127
Create a C# Console Project
First of all create a C# Console Project supporting the latest .NET Core and the C# version 11 or later.
// SupplierBill.cs in Models folder
internal sealed record class SupplierBill(String? Supplier, int BillAmount);
Create a models folder and add a record class called SupplierBills to hold two properties string? Supplier and int BillAmount.
Program.cs File
Next let us complete the program.cs file.
// program.cs string desktopDir = Environment.GetFolderPath( Environment.SpecialFolder.Desktop); string RECORDSFILE = Path.Combine(desktopDir, "records.txt"); string REPORTFILE = Path.Combine(desktopDir, "report.txt"); List<SupplierBill> allBills = new(); foreach (string line in File.ReadLines(RECORDSFILE)) { SupplierBill? bill = null; try { bill = line.Split(",") switch { // upgrade to version C# 11 [var code, var amt] => new (code, Convert.ToInt32(amt)), _ => throw new FormatException() }; } catch (FormatException) { Console.WriteLine($"ERROR at {line}"); return; } allBills.Add(bill); } // using declaration will dispose sw // scoping is implicit using StreamWriter sw = new (REPORTFILE); foreach (var bill in allBills.OrderBy(bill => bill.BillAmount)) { sw.WriteLine($"{bill.Supplier},{bill.BillAmount}"); } sw.WriteLine("========="); sw.WriteLine($"Total {allBills.Sum(bill => bill.BillAmount)}");
Create a list to hold all the records. We shall read the file line by line and extract records into this list.
A for-each loop streams lines from the file one by one. We have used the function File.ReadLines() to stream the lines through IEnumerable.
The line is split into an array on the comma separator, and then pattern matching has been used with switch expression to extract a record or throw a FormatException on failure. Please remember that pattern matching works on C# 11 or later. You will have to upgrade Visual Studio to compile for C# 11 or later.
If the record is extracted, it is added to the list of bills.
A StreamWriter is opened with a using declaration so that the streamwriter is automatically disposed when the object is no longer referenced.
LINQ is used to order the records on BillAmount and a for-each loop is used to printed them to the streamwriter.
Finally, we have again used LINQ to find the sum of all bill amounts and write to the streamwriter.
You can appreciate the brevity of this code!
THE FILE "records.txt" MUST BE PLACED ON DESKTOP BEFORE YOU RUNPlace the "records.txt" file on the desktop and run the project to verify that it works as expected.
This Blog Post/Article "(C# Language) Project Exercise on CSV Processing" by Parveen is licensed under a Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International License.