C++ Programming Series: File I/O

In this post, we are going to discuss about input and output. No, I am not talking about cout, cin, getline() or any other methods we have discussed till now. I am talking about writing and reading files.

For working with files, we need to include another header called fstream.

There are three classes in it, for file I/O:

  • ofstream – Class for writing files
  • ifstream – Class for reading files
  • fstream – Class for writing as well as reading files

We are going to discuss ofstream and ifstream only. fstream is a bit different to use but who cares! We don’t need that!

The codes for file I/O are present below. It is pretty simple and there is more comment in the code than the code itself, for explaining things!

File Writing:

#include <iostream>
#include <fstream>

using namespace std;

int main()
{
  //The 'ofstream' class for writing a file
  ofstream fileWriter("a_file.txt");

  int number = 21;

  //Writing the stuff
  fileWriter << number;
  fileWriter << " ";
  fileWriter << 13;

  //Closing that file which is opened; it is important!
  fileWriter.close();

  return 0;
}

File Reading:

#include <iostream>
#include <fstream>
using namespace std;

int main()
{
  //The 'ifstream' class for reading a file
  ifstream fileReader;

  //Opening a file called 'a_file.txt' in local directory
  fileReader.open("a_file.txt");

  //For checking whether the file fails to open or not
  if (fileReader.fail())
    cout << "There is no file in the address!" << endl;

  //While the file that is opened, has some context
  //in it at the pointer location
  while (fileReader.good())
  {
    //Variable to store reading from the file
    int number;

    //Reading the number at the pointer location and then,
    //proceeding the pointer forward for further reading
    fileReader >> number;

    //Displaying the number present in the file
    cout << number << endl;
  }

  //Closing that file which is opened; it is important!
  fileReader.close();

  return 0;
}

Reading and writing a file requires us to have the concept of a pointer. The pointer points to some place in the file which then, proceeds forward with every single read/write operation. That pointer is similar to the one which appears at the time of typing.

I hope that you understood how to read and write a file. But there are still some doubts and confusions!

The first one is the formatting of the file that we are reading. White spaces are something that no one wants to read/get from the file. So, ifstream don’t consider these spaces and no matter how much white space there is, it will be considered as one space only.

Of course, we can’t just read data as discrete if that data is arranged without spaces in between. For example, if the file contains two words without any space like this, “nospace”, ifstream reads it as “nospace” and so, giving a space between them rectifies the issue.

The second one is the data type for reading and writing a file. We can use all primitive types. We can use strings as well if we include the string header.

The third one is formatting a file being written. We can have formatting by just writing in character literals like \t or \n to have a tab or a new line respectively.

This is how we simply read and write files. Now, your task is to modify the registration program that we made with functions previously, to write a file with the data inputted by the user.

Soon we will see, how much fun is programming! It is fun for me as I am developing a game in C++ called SamuraiDuel.

C++ Programming Series: Functions/Subroutines (Part 4, Last)

In the previous post, I confused you into the depth of the functions and my abstractions although, I hope that you got the concept fairly. The hint that I gave you in the previous post is about the order of the functions. If you modified checkRegistrationEligibility() function by adding enterAString() and enterAnInt(), you may have got some error because checkRegistrationEligibility() function don’t know anything about enterAString() and enterAnInt() since, they are both defined as well as declared below the function. The issue with the order of the functions can be fixed but I will explain this later!

The functions with which we get father’s name, place of living and education in the previous post are very similar to each other. In fact, they are just the same with the exception to the statement being printed out!

Fortunately, there are more ways! Until now, we are just getting outputs from the functions in the form of returning values. But in many cases, it is necessary to have inputs in the functions. If you recall the first post on the topic of Functions/Subroutines, we discussed that a function takes the input, modifies it and then, outputs the modified input. We can always have the user input but there are many many cases where user input is not the solution! A pair of round brackets after the end of each function is not useless; it is for taking data into the function(inputs) or in other words, for taking parameters.

I had given you the task for creating a function which takes the user input for the number to be squared and then, returns the square of that number. Here it is done with a function that takes the input from the parameter, squares it and then, returns it.

int square( int value ) //a parameter of type 'int'
{
  return (value * value);
}

int main()
{
  //In 'square' function, we pass 5 as a parameter, giving us 25 as a return value.
  cout << square(5) << endl; //Outputs 25
  return 0;
}

This might have given you the idea of how parameters of a function works. Let us remove the three functions as described in the previous post namely, enterYourFatherName(), enterYourPlace() and enterYourEducation() and replace it with only one function!

string enterRequiredData( string required_data ) //a parameter of type string
{
  string data = "NULL";
  do
  {
    cout << "Enter your " << required_data << ": " << endl;
    data = enterAString();
    cout << "Is your " << required_data << " " << data << "?" << endl;
 
  } while (!isDataSure());

  cout << "Your " << required_data << " is " << data << "." << endl;
  return data;
}

Now, in the registrationSection() function:

void registrationSection()
{
  enterRequiredData("father\'s name");
  enterRequiredData("place of living");
  enterRequiredData("education");
}

All the other codes will remain same! You can see that a single function is doing quite a job because of the fact that it is more flexible now. The output of a function should depend on the parameters being given into it or else, the function should have no inputs/parameters at all. However, it is not necessary to use the output of a function for something else. In the codes above, we haven’t used the strings being returned by the functions inside the registrationSection(). We can store them in a separate file which is the prime purpose of registration (We will discuss about getting data into and out of a file soon).

That’s all! Function parameters are awesome! But there are still few problems that we may encounter, the first one is the order of functions and the second one is getting multiple outputs. You haven’t seen any example of multiple inputs/parameters as well. There you go!

int clamp(int value, int min, int max)
{
  if(value < min)
    return min;
  else if(value > max)
    return max;

  return value;
}

Try to code functions with multiple parameters and have fun with them!

C++ Programming Series: Functions/Subroutines (Part 3)

In the previous post, we have played with a function called checkRegistrationEligibility(). It was first, a function of return-type, void and now, bool. What is good with this, is the fact that this function is able to connect. From being connected, we mean that the data available in a limited scope of a function, can get available to that other function from which this function is called!

We can get the output from that function in the form of a boolean value. It is not necessary to collect the output of a function by having a specific variable for it. You can have a stupid line of code like 5+5; or true; without having any cout at the back! Sometimes, a function is of return-type int which returns a value 1, 0 or -1 only to indicate whether there is some error in the function or not and so, is not necessarily, taken into account.

In this post, we are not going to change even a bit of checkRegistrationEligibility() function. It is now, perfect. What we will do now, is to create another function for the next section of the registration program. But this time, we will create many small functions which will be grouped into more functions until a big function is created! If you don’t know about the checkRegistrationEligibility() function, please visit this post first!

Two very simple input functions which takes user input and then, return that input:

string enterAString()
{
  string str;
  getline(cin, str);
  return str;
}

int enterAnInt()
{
  int integer;
  cin >> integer; //Remember, getline() is for strings only!

  //the 'cin >>' causes rubbish in the input stream
  //which causes problems with getline()
  //the line below is a fix to it
  //it should be after every 'cin >>'
  cin.ignore();

  return integer;
}

Another function which makes sure than the user said ‘Yes’, ‘yes’, ‘Y’ or ‘y’ for reasons that are going to be obvious in the other functions.

bool isDataSure()
{
  string yes_or_no = enterAString();

  if (yes_or_no == "yes" || yes_or_no == "Yes" ||
    yes_or_no == "y" || yes_or_no == "Y")
    return true;

  //Remember, function stops to go further immediately after the 'return' keyword
  //So, there is no need for 'else'
  return false;
}

If you don’t know or just forgot the complex if conditions or just confused about the condition as the above one, just go through this post.

Now, three more functions for getting father’s name, place of living and education.

string enterYourFatherName()
{
  string father = "NULL";
  do
  {
    cout << "Enter your father\'s name: ";

    //If 'father' is declared inside, we can't return it from outside
    father = enterAString();

    cout << "Is your father\'s name " << father << "?" << endl;

  } while (!isDataSure()); //Remember, semi-colon is necessary after do-while-statement

  cout << "Your father\'s name is " << father << "." << endl;
  return father;
}

string enterYourPlace()
{
  string place = "NULL";
  do
  {
    cout << "Enter your place of living: ";
    place = enterAString();
    cout << "Is your place of living " << place << "?" << endl;
  } while (!isDataSure());
  cout << "Your place of living is " << place << "." << endl;
  return place;
}

string enterYourEducation()
{
  string education = "NULL";
  do
  {
    cout << "Enter your education: ";
    education = enterAString();
    cout << "Is your education " << education << "?" << endl;
  } while (!isDataSure());
  cout << "Your education is " << education << "." << endl;
  return education;
}

Finally, a function to have all the three functions and the main function is all set!

void registerationSection()
{
  //To keep some distance from the first section
  cout << endl;

  //Discarding the returning strings for now...
  //It can be used for various purposes!
  enterYourFatherName();
  enterYourPlace();
  enterYourEducation();
}

int main()
{
  //Instead of making a 'bool' variable and then, storing the value received
  //by checkRegistrationEligibility() method, how about using it directly?

  if (checkRegistrationEligibility() == true)
    registerationSection();

  //We can also use 'if (checkRegistrationEligibility())'
  //instead of 'if (checkRegistrationEligibility() == true)'
  return 0;
}

Here you go! All set for now accept for one thing which you will do yourself! The checkRegistrationEligibility() function requires some changes. Make sure to have enterAString() and enterAnInt() methods in it instead of the old regular methods. It is very important because we need cin.ignore() to ignore the leftovers in the input stream after cin >> to avoid problems with getline() method.

NOTE: The getline() is also a function from the standard C++ library. Same is the case for ignore() after cin. We will face many of standard C++ library functions!

After modifiying the checkRegistrationEligibility() function, it will run fine and you will be happy by the results for sure! It is easy to understand something like enterAString than the regular getline(cin,... method. Same is the case with isDataSure() which actually, gives us the hint that this function belongs to something like conforming the data to be right. In a nut shell, with the help of functions, we can make our own unique language which is understandable to everyone and not just programmers! This is something that we call as abstractions! Abstractions make things very easy. In programming, it is not simple to have even a very small task done with our basic English language. Computers don’t understand what we mean by what we say. But an approach like creating abstractions is possible. All the things we see are 0’s and 1’s which are later on, combined to form complex structures given complex names and so on. The binary can be used to define anything with reference to a name!

We defined our 0’s and 1’s into functions like enterAString(), isDataSure(), etc. The concept is to make abstractions and then, use them as much as possible to make even more abstractions. We can’t say our monitor’s screen consists of something like 0101001… but we can say it as ‘pixels’.

For now, this is it! I hope that this fulfills my promise which I talked about in the previous post and I think this much code is hard to absorb for a beginner! But don’t lose here… If code goes wrong just try, try again! Here’s a hint: See what can go wrong when we change the order of the functions! Or if you are already getting an error, see what can go right when we change the order of the functions!

C++ Programming Series: Using Conditional Statements (Part 4)

In the last few previous posts, we learned some of the conditional statements, user input and basic arithmetic. Now, time to use some bits of all of them in one place!

Just like if-statements, there is another conditional statement called as while-statement. Below is a very simple example of this:

while(true)
{
  cout << "Looping..." << endl;
}

When you run this code, you might be wandering that why the program is not stopping? Well, it’s because it is an infinite loop. After the while keyword, there is a condition just like that of if-statement. The code in the braces, will keep repeating itself while the condition after the while is true. Ofcourse, you got the meaning! It is just like a recurring if-statement.

We can do some interesting things with it like this:

int loopCounter = 0;
while(loopCounter < 10)
{
  cout << "Looping " << ++loopCounter << endl;
}

When we run this code, we see that the word “Looping” along with a increasing number, is printed 10 times. The increasing number starts to print from a value, 1. It will start from a value, 0, with postfix increment operator(loopCounter++). We can also do loopCounter = loopCounter + 1; or loopCounter += 1; at the end or start of the braces of while-statement.

Can you think of some program that uses while-statement along with getline(user input)? Password input! Check out the code below:

#include <iostream>
#include <string>
using namespace std;

int main()
{
  string password = "kabrakadabra";
  string entry = "NULL";

  while(entry != password)
  {
    cout << "Enter your password: ";
    getline(cin, entry);
  }

  cout << "Correct password!" << endl;

  return 0;
}

What if we want to say wrong password each time it is entered wrong! Then, below the getline, we can add:

if(entry != password)
{
  cout << "Wrong password! Please try again!" << endl;
}

Don’t you think that it’s perfect? Woohoo! we are going to be true programmers in the future, don’t we? Yes, but only if you do few experiments with it as a home task!

C++ Programming Series: User Input and Comments

I am too busy last month! Sorry for such a big delay!

In the previous post, we talked about user input. Well, there’s no post about user input until now.

A very simple user input program is given below:

#include <iostream>
#include <string>
using namespace std;

int main()
{
  cout << "Enter your name: ";

  string name;
  cin >> name;
 
  cout << "Your name is " << name << "." << endl;
 
  return 0;
}

This program will get the input from us and then, outputs our input. There are many new things to notice:

  • This time, we also included string in our program. String is nothing special, just a group of characters with some useful functions(we will discuss it later, in detail). The only point to get in our minds is that, string is not a primitive type. Just like including string allows us to use strings in our program, including iostream allows us to use cout, endl and cin.
  • endl is not important for using cout. endl can be used anywhere after cout << and is used to skip the present line.
  • cin is the standard method for getting input from user. Once you typed the input, you need to press enter to proceed. For output, we use << and for input, >>.

In the same way, you can input integer. Integer is not a group of characters so, trying to assign an integer, group of characters will give us nothing.

Are you facing some problems? Try to input more than one words like: ‘Robo Tex’. Is there some problem with the output? Here’s the output:

Your name is Robo.

Where’s Tex? The problem is that cin ends when a space comes in its way! Instead of cin, we can use getline:

cout << "Enter your name: ";

string name;
//cin >> name;
getline(cin, name);
 
cout << "Your name is " << name << "." << endl;

This will solve the problem. cin takes a word from input buffer whereas getline takes a line from input buffer. In the getline, you have to specify at least two things. First one is the input method which is cin and the second one is the variable to be filled with input.

Have you noticed that //cin >> name; is not doing anything in the code? This is a single line comment. Whatever is after double slashes, it will not be checked by compiler and will only affect that line. For making multi-line comments, use /* and */. The code between /* and */ is not considered by the compiler.

Commenting never influences the performance of a program. It is used in order to make notes with the code, describe the code for an easy understanding and removing the codes temporarily from the program. It is very useful and so, we will use it so much!

Example of a single line and multi-line commenting:

/*This is a
multi-line comment.
Following code takes a line from input buffer:
*/
cout << "Enter your name: ";

//Getting input.
string name;
//cin >> name;
getline(cin, name);
 
//Outputting the input.
cout << "Your name is " << name << "." << endl;

cin and getline requires pressing enter to shift input to the variable. You can have input without pressing enter by using getch which takes a character from input buffer and also removes that character from the screen unlike cin and getline. We must include conio.h to use getch in our program just like string.

With other includings (e.g iostream), #include <conio.h>

In the main function, (i.e in the flower brackets below int main())

cout << "Enter a character..." << endl;

char input;
//cin >> input;
input = getch();
 
cout << "Character: " << input << endl;

We can do many fun stuff with user input and conditional statements together. But for now, this is it!

Note: We can use string type without including string. This is because it is also in the iostream. But we can’t use it with cout unless we include string.

C++ Programming Series: Using Conditional Statements (Part 3)

In the last two previous posts, you got through the if, else and else-if-statements. The uncertain point is the difference between two if-statements and if-statement with an else-if-statement.

Two if-statements are not connected to each other. They don’t have any relation with each other. The compiler have to pass through all of these statements even if anyone of the conditions is true. Example shows three if-statements:

int value = 6;
if(value > 7)
  cout << "value is bigger than 7" << endl;
if(value > 5)
  cout << "value is bigger than 5" << endl;
if(value > 3)
  cout << "value is bigger than 3" << endl;

Output:

value is bigger than 5
value is bigger than 3

An if-statement with an else-if statement are connected to each other. If anyone of the conditions gets true, all others are skipped. Same example below with some corrections:

int value = 6;
if(value > 7)
  cout << "value is bigger than 7" << endl;
else if(value > 5)
  cout << "value is bigger than 5" << endl;
else if(value > 3)
  cout << "value is bigger than 3" << endl;

Output: (Now, there is no unnecessary outputs. It is pretty nonsense to say that value is bigger than 3 when we already said that value is bigger than 5)

value is bigger than 5

This is very important when it comes to getting user input and then, manipulating it for some change in the output. For example, there is a character variable or variable of type, char called key which takes the character (or letter) that you press on the keyboard and in return, print something for you. (Remember, put single inverted commas and not double, for a character or their variables only)

if(key == 'a')
  cout << "Alpha!" << endl;
else if(key == 'b')
  cout << "Beta!" << endl;
else if(key == 'c')
  cout << "Charlie!" << endl;
else if(key == 'd')
  cout << "Delta!" << endl;
else
  cout << "Unknown input..." << endl;

For such cases, it is better to use another conditional statement called as switch-statement. It is only good for comparison done with equality operator (i.e, ==) and numbers.

switch(key)
{
case 'a':
  cout << "Alpha!" << endl;
  break;
 
case 'b':
  cout << "Beta!" << endl;
  break;
 
case 'c':
  cout << "Charlie!" << endl;
  break;
 
case 'd':
  cout << "Delta!" << endl;
  break;
 
default:
  cout << "Unknown input..." << endl;
  break;
}

This code do the same thing as the above one. You may have figured out some of the things by yourself. But let me explain this.

After switch, we have to type in the variable in the round brackets unlike if-statement. Then, we need to put a case with the value that is to be compared with the variable. At the end of case-value pair, we need to put a colon. Then, put one to many lines of code before the ending flower bracket. What? Did we put a starting flower(or curly) bracket? No! So, that means… there is some other way to put an ending to it. The break keyword is only for switch and loop statements. It is used to skip all the codes below it and is used to skip the whole loop, not just a block (You will understand this later if not now). The default keyword is another case which acts like the else-statement and works only when all the above cases are false.

Want some shortcut to understand switch-statement? Here is the format:

switch( [variable] )
{
case [value]:
  // to be executed when variable's value is equal to that of case's value
  break;
  // ...
// [more cases]
  // ...
default:
  // to be executed when variable's value is not equal to any of the above case's value
  break;
}

Pretty long but looks useless! Nah! These are the basis of all beautiful things that you can imagine to do on the screen…