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.
Many times when we’re busy churning out code and worrying about the accuracy of our calculations, we can forget that ultimately our users are looking at the results. We have to care about how to present those precious calculations so our users can make sense of it.
So you’ve learnt a bit about
Arrays offer a simple syntax to declare a series of variables of the same type with minimum work. Think of arrays as boxes in sequential order, where the boxes can only hold a certain type of item.

I write about maths, programming, entrepreneurship and business stuff. I also make videos.







Beginning C# – Precision and control
So you’ve learnt about variables, and you’re wondering, “What’s the practical difference between float, double and decimal variable types?” The difference is in precision.
floats represent single precision real numbers, known as such because of the floating point (or decimal point).doubles represent double precision real numbers, taking up two times the storage space of afloat(different from representing two times the range of a float).decimals are a bit special, as they can represent up to 28 significant figures. It’s easier to just show you, so here’s the example code (only contents of the Main function).float lowprecision; double highprecision; decimal exactprecision; lowprecision = 1.61803398874989484820f; highprecision = 1.61803398874989484820; exactprecision = 1.61803398874989484820m; Console.WriteLine(lowprecision); Console.WriteLine(highprecision); Console.WriteLine(exactprecision); if (5 > 3) { Console.WriteLine("First condition"); } else { Console.WriteLine("Second condition"); } // variables can be declared and assigned a value // on the same line of code. int truthchecker = 17; if (truthchecker == 17) { Console.WriteLine("The truth is the number 17."); } if (truthchecker != 17) { Console.WriteLine("The truth is NOT the number 17."); } /* The following if-else statement is equivalent to the above * two if statements. * This comment also illustrates how to use a multiline comment. * */ if (truthchecker == 17) { Console.WriteLine("2nd check: The truth is the number 17."); } else { Console.WriteLine("2nd check: The truth is NOT the number 17."); } Console.WriteLine("End of program"); Console.ReadLine();I’ve used a prominent mathematical number, the golden ratio, as an assigned value for our
float,doubleanddecimalvariables. You should have noticed the “f” at the end of golden ratio for thefloatvariable assignment, and the “m” for thedecimalvariable. These are known as suffixes, and there are other suffixes for other variable types. For now, just remember to append an “f” forfloats, and an “m” fordecimals.Output for float, double and decimal
When you print the variables, you get 1.618034, 1.61803398874989 and 1.61803398874989484820 respectively. The difference is due to the size of the variable type, affecting how a variable stores a value. So even though the assigned value is the same, the storage and thus the stored value is different for the three variables.
One practical use of preferring
floats over the other two types is their speed. Smaller storage sizes translates to faster calculation speeds, while sacrificing accuracy. This is particularly useful in games, such as calculating 3D positional points where the results don’t have to be accurate as much as being quickly computed. The player isn’t going to notice that a box is 0.000005 units off to the left, because he’s too busy shooting some dastardly evil aliens.When accuracy is extremely important, such as in financial applications,
decimals come into play. There are real numbers thatfloats anddoubles cannot represent exactly. For example, the only money values afloatordoublecan represent exactly are 0.00, 0.25, 0.50 and 0.75 (or any dollar amount with those cent values, like 14.75). Why is this? Short answer is it’ll take too long to explain. Try searching with the words “exponent” and “mantissa”. Anyway, with 28 significant figures for accuracy,decimals are ideal for financial applications.Decisions, choices and forks
Next we learn a new concept: the
ifstatement, one of the most powerful and most used construct for controlling program logic flow.if (5 > 3) { Console.WriteLine("First condition"); } else { Console.WriteLine("Second condition"); }Note where the round brackets () and the curly brackets {} are used.
The above code can be read as “If 5 is greater than 3, then print ‘First condition’, otherwise, print ‘Second condition’”.
The
ifstatement can also be used alone without theelsepart, such asif (truthchecker == 17) { Console.WriteLine("The truth is the number 17."); }Note: The double equals mean mathematical equality. A single equal mean assignment.
In English, the above code reads “If the variable ‘truthchecker’ is equal to the number 17, print ‘The truth is the number 17.’” Some programmers prefer to reverse the check, like “
17 == truthchecker“, to avoid confusing equality checks and assignments. I find it kinda funny to check in reverse, so take your pick.Then there’s the converse.
if (truthchecker != 17) { Console.WriteLine("The truth is NOT the number 17."); }The exclamation mark followed immediately by an equal sign means “not equal to”. So the chunk of code reads “If the variable ‘truthchecker’ is not equal to the number 17, print ‘The truth is NOT the number 17.’”
Multiline commenting
Two consecutive forward slashes
//means whatever follows on the same line is a comment, and to be ignored by the computer. What if your comments are too long and go over the next line? You can start another line with//and continue writing comments. Or if you can start your comments with a forward slash and an asterisk/*and end your comments with an asterisk and a forward slash*/, which achieves the same effect.Homework
Wow, that was a long lesson. So homework will be short. Download the source code, and replace the line
with
Change the numbers around and see what happens.