Beginning C# – Reading Input Writing Output

There’s a saying in programming that goes something like this

Be liberal with what you receive. Be strict with what you produce.

What it means is that your program should be lenient with the input it receives, to assume that all sorts of rubbish data can (and will be) fed to your program, and it’s your duty to make sure your program can handle it.

BUT, your program must adhere strictly to the output format it’s supposed to produce. If your program’s supposed to write out integers, it better write out only integers.

It’s not fair, I know. It also makes it easier for programs to talk to each other, since input and output of programs are what they communicate with. The most common communication methods is through file input/output or file IO as they’re usually referred to.

I personally find the StreamReader and StreamWriter classes to be easy to use for file IO. The .NET framework views file IO as a form of data stream. Other classes dealing with data streams include NetworkStream (working with data across networks) and MemoryStream (working with data within computer memory).

So how do we read input and write output? Let’s look at some source code first. [code formatting looks better from web site]

StreamWriter sw;
sw = new StreamWriter("greetings.txt");
sw.WriteLine("Hi!");
sw.WriteLine("Good morning!");
sw.WriteLine("Splendid day isn't it?");
sw.Close();

string[] flowerlist = new string[] { "daffodil", "lily", "orchid", "rose" };
sw = new StreamWriter("flowers.txt");
foreach (string s in flowerlist)
{
    sw.WriteLine(s);
}
sw.Close();

// the second parameter indicates if file should be appended or not.
// If the second parameter is false, it would have overwritten the
// contents from above, and flowers.txt would only have 2 flowers.
sw = new StreamWriter("flowers.txt", true);
sw.WriteLine("sunflower");
sw.WriteLine("tulip");
sw.Close();

File.WriteAllLines("greetings2.txt", new string[] { "Hello!", "How are you doing?" });

// we start reading the files and writing their content here
sw = new StreamWriter("result.txt");
StreamReader sr;

sw.WriteLine("{0}Reading from greetings.txt", "=".PadRight(20, '='));
sr = new StreamReader("greetings.txt");
while (sr.Peek() > -1)
{
   // we read one line and write one line
   sw.WriteLine(sr.ReadLine());
}
sr.Close();
sw.WriteLine("{0}End of greetings.txt", "=".PadRight(20, '='));

sw.WriteLine("{0}Reading from flowers.txt", "=".PadRight(20, '='));
sr = new StreamReader("flowers.txt");
// we use sw.Write() instead of sw.WriteLine() because
// flowers.txt already contained a newline character at the end.
sw.Write(sr.ReadToEnd());
sr.Close();
sw.WriteLine("{0}End of flowers.txt", "=".PadRight(20, '='));

sw.WriteLine("{0}Reading from greetings2.txt", "=".PadRight(20, '='));
sw.WriteLine(File.ReadAllText("greetings2.txt"));
sw.WriteLine("{0}End of greetings2.txt", "=".PadRight(20, '='));

sw.Close();

Console.WriteLine("End of program");
Console.ReadLine();

The code’s quite straight forward. I want to highlight a small code section

"=".PadRight(20, '=')

This is a shortcut to generate 20 equal signs. It beats writing a for loop or manually typing in 20 equal signs.

The StreamReader.Peek() function returns the next character but doesn’t read it into memory. If there’s nothing left to read, like End Of File (EOF), then a -1 is returned. This makes the function a suitable termination condition for a while loop reading in file content.

The StreamReader.ReadLine() function reads in input until it hits a newline character, and returns all input read thus far in a string. The StreamReader.ReadToEnd() function basically dumps the entire file content into a string.

With .NET framework 2.0 comes another way to rapidly and easily read data from files. The File class has been beefed up with some nifty new functions. The following functions allow reading in input from a file with just one line of code

  • File.ReadAllBytes() – returns file content in a byte array
  • File.ReadAllLines() – returns file content in a string array
  • File.ReadAllText() – returns file content in just one string (newlines and all)

Then there’s the corresponding one-liners for writing output

  • File.WriteAllBytes()
  • File.WriteAllLines()
  • File.WriteAllText()

These one-liners read/write content to/from a file and closes the file, all in that one line. It’s basically a shortcut compressing one line to open a file, one line to read/write file content, and one line to close the file.

As always, you are encouraged to explore the (online) MSDN documentation for more details. Study how to instantiate a class and what are the public properties and functions available.

You don’t have to memorise and learn how to use every single function. Just remember what kinds of functions are available. Then when the time comes where you need a particular feature, you’ll know where to look.

Download the source code.

Comments are closed.