Exercise: File I/O

Read a school's grades from a CSV file with mistakes in it, log every line you can't read with your own LogService, write an honor roll, and add new students to the end of a file.

Journeyman · C# · Updated

A school keeps its students' grades in a CSV file exported from a spreadsheet. Like most real files, it has mistakes in it: a line with a missing column, a GPA of n/a, a blank line at the end. You'll write the code that reads it anyway, logs what it can't read, and writes new files from it.

Get the exercise code

Open this lesson's GitHub repository, github.com/ask-codey/exercise-file-i-o, also linked from the Exercise box beside the lesson. Click Code, then Download ZIP, and unzip it into your bootcamp folder. Or clone it with Git. Then open GradeBook.slnx in Visual Studio.

File What's in it
GradeBook/data/student_grades.csv The school's file, mistakes and all. It's set to Copy if newer, so it's copied next to the program when it builds.
GradeBook/Student.cs, IClock.cs, SystemClock.cs Finished
GradeBook/LogService.cs A log file per day, for you to finish
GradeBook/GradeFile.cs Reads and writes the CSV files, for you to finish
GradeBook.Tests Tests for both. They work in a temporary folder, with a fake clock.

The requirements are in the comment at the top of each file you finish.

What to do

Member What it does
LogService.CurrentFilePath Today's file in the log folder, such as logs\errors\20260314.log
LogService.Log(message) Appends 2026-03-14 21:05:09 message, creating the folder and file if needed, and never crashing the app
GradeFile.Read(path) The students in the file. Skips the header and blank lines; skips and logs each bad line with its line number; logs a missing file and returns an empty list.
GradeFile.WriteHonorRoll(path, students, minimumGpa) A new file with the header and every student at or above the minimum
GradeFile.AddStudent(path, student) One line at the end of the file, with the header first if the file is new

Run the program with Ctrl+F5, and the tests with Test > Run All Tests.

Hints

  • Start with LogService. Read logs through it, and its tests are the simplest.
  • Dates: {clock.Now:yyyyMMdd} for the file name and {clock.Now:yyyy-MM-dd HH:mm:ss} for an entry. Capital HH is the 24-hour clock; capital MM is the month.
  • Count the lines in Read as you go, starting from 1 for the header, so a logged line number matches what you'd see in an editor.
  • A bad line is expected, not exceptional: check it with columns.Length and decimal.TryParse. A missing file is the one thing to catch.
  • Replace or append? WriteHonorRoll replaces; AddStudent appends. Check File.Exists before opening the writer, to know whether a new file needs its header.

When you're done

Every test passes, and the program prints (with today's date):

Read 8 students
firstname,lastname,gpa
Emily,Wilson,3.91
Jane,Garcia,3.96
James,Miller,3.85

Problems logged in logs\errors\20260314.log:
2026-03-14 13:34:28 student_grades.csv line 7: can't read 'David,Jones'
2026-03-14 13:34:28 student_grades.csv line 10: can't read 'Michael,Davis,n/a'

Open student_grades.csv and check lines 7 and 10: that's what a good log does, it sends you straight to the problem.

Submit your exercise

The exercise is how you finish this lesson. When your work is done, put it on GitHub in a repo of your own, then submit that repo's address here.

  1. On GitHub, click +, then New repository. Name it (for example exercise-file-i-o), choose Public, and click Create repository. Leave out the README: your folder already has one.

  2. In a terminal in your exercise folder (Git Bash on Windows), send your work to your new repo. If you downloaded the ZIP:

    git init -b main
    git add .
    git commit -m "My solution"
    git remote add origin https://github.com/your-name/exercise-file-i-o.git
    git push -u origin main
    

    If you cloned the starter instead, point your copy at your own repo, then commit and push:

    git remote set-url origin https://github.com/your-name/exercise-file-i-o.git
    git add .
    git commit -m "My solution"
    git push -u origin main
    
  3. Paste your repo's address, such as https://github.com/your-name/exercise-file-i-o, into Submit your exercise on this page. The site checks that the repo is public and holds your commits, and then the lesson is complete.

Changed something after you submitted? Push it, and submit again: your latest submission is the one that counts.

So what

Real files are messy. Code that reads the good lines, logs the bad ones with enough detail to fix them, and never crashes over a missing file is code people can trust with their data.

Key terms

Related