CommonLounge Archive

C++: Sorting and File Input-Output

September 24, 2018

In this tutorial you will first learn about sorting, i.e. how to sort vectors and arrays. After that, you will also learn how to read from a file and write to a file using C++.

Sorting

The easiest way to sort any container is with the sort() function from the algorithm library, which takes two arguments. First argument is the beginning address (container.begin()) of the container and second argument is the ending address (container.end()). Remember, this function doesn’t return any value. Calling the sort function modifies the original container and the elements are arranged in sorted order.

The general syntax for sorting is:

sort(start address, end address)
start address = the address of the first element of the array / vector
end address = the address of the last element of the array / vector

Sorting an array

For an array named arr having n elements, address of first element of array is given by arr and the address of last element is arr + n. Let’s see an example:

#include <iostream>
#include <algorithm>
using namespace std; 
int main() { 
    int arr[] = {1, 7, 4, 2};
    int n = 4; 
    sort(arr, arr + n); // Sort 
    // Output
    for (int i = 0; i < n; i++) {
        cout << arr[i] << " ";
    }
}

Output:

1 2 4 7

Sorting a vector

You have already sorted vectors in previous tutorials. Now, you understand why you used v.begin() and v.end() as arguments to sort vector v, as they represented the beginning and ending address of the vector.

Let’s see an example of sorting a vector:

#include <iostream>
#include <vector>
#include <algorithm>
using namespace std; 
int main() { 
    vector <int> vec {5, 1, 4, 3};
    sort(vec.begin(), vec.end()); // Sort 
    // Output
    for (int i = 0; i < vec.size(); i++) {
        cout << vec[i] << " ";
    }
}

Output:

1 3 4 5

Sorting in descending order

By default, sort() will sort your array in ascending order. The sort function also takes an optional third argument — a function which tells sort() how to sort the container. For example, to sort the container in descending order, you have to write greater<int>() as your third argument.

int arr[] = {1, 7, 4, 2};
int n = 4; 
sort(arr, arr + n, greater<int>()); 
for (int i = 0; i < n; i++) {
    cout << arr[i] << " ";
}

Output:

7 4 2 1

Sorting using your own comparison function

In general, the third argument can be any comparison function. A comparison function tells the sort function given two values, which one should come first in the sorted order.

The default comparator sorts your container in ascending order, and as you saw greater<int>() comparator sorts the container in descending order.


Let’s write our own comparator which will sort an array in descending order.

bool descending(int a, int b) {
    return a > b;
}
int main() {
    int arr[4] = {9, 5, 7, 10};
    sort(arr, arr + 4, descending);
    for (int i = 0; i < 4; i++) {
        cout << arr[i] << " ";
    }
}

Output:

10 9 7 5

First, let’s look at the comparison function. The function returns true if a > b and returns false otherwise. In general, the comparison function needs to return true if the first argument should come before the second argument, and false otherwise.

The general syntax of the sort function using a custom comparator is:

sort(container.begin(), container.end(), comparison_function);

where comparison_function is the name of function that you will create. The sort function will use this comparison function to perform the sorting and decide the order of the elements.


Let’s see another example. This time, we will sort strings by their length — that is, we want the shortest string to come first, and the longest one should be at the end.

bool ascending(string &a, string &b) {
    return a.size() < b.size();
}
int main() {
    string arr[4] = {"Violet", "Blue", "Red", "Green"};
    sort(arr, arr+4, ascending);
    for (int i = 0; i < 4; i++) {
        cout << arr[i] << " ";
    }
}

Output:

Red Blue Green Violet 

Since we want the strings to be sorted by length, our comparison function returns true if and only if a.size() < b.size().

Sorting using a custom comparison function is extremely powerful and useful.

File Input-Output

Often, in your projects, you will want to read data directly from a file or even write directly to a file instead of showing the output on console. In C++, you can use the fstream standard library to read from files and write to files. fstream stands for file stream.

Note: If you want to follow along and try out the code snippets shown below, you will need to have C++ installed on your computer to complete this project. If you haven’t installed C++ yet, see installation instructions here.

File Output

The fstream library works just like iostream library — the only difference is that you need to (a) create a file variable and (b) open a file before reading / writing to it, and you need to close the file after you are done. Let’s see an example:

#include <fstream>
using namespace std;
int main() {
    // Declare the variable and open the file
    ofstream output_file;
    output_file.open("super.txt");
    // Write something to the file
    string name = "Batman";
    output_file << "My favorite superhero is " << name << endl;
    // Just like "cout << "My favorite superhero is " << name << endl;"
    // Close the file once done
    output_file.close();
    return 0;
}

This will create a file super.txt on your computer with the text:

My favorite superhero is Batman

Just like we define an integer variable named a by int a, similarly we define a variable for file handling. Here ofstream is the data type (stands for output file stream), and output_file is the variable. Once you open the ofstream, it works just like cout.

File Input

Similarly, you can take input from a file using ifstream and the >> operator. Create a file favorite_number.txt with just a number in it:

42

Then,

#include <iostream>
#include <fstream>
using namespace std;
int main() {
    // Declare the variable and open the file
    ifstream input_file;
    input_file.open("favorite_number.txt");
    // Read from the file
    int favorite_number;
    input_file >> favorite_number;
    // Just like "cin >> favorite_number;"
    cout << "My favorite number is " << favorite_number << endl;
    // Close the file once done
    input_file.close();
    return 0;
}

Produces the output:

My favorite number is 42

The getline() function

One last thing about file input-output. Sometimes, you want to have the ability to take an entire sentence as input (or allow spaces in the string we are inputting). You can do this using the getline() function.

For example:

#include <iostream>
#include <fstream>
using namespace std;
int main() {
    // Declare the variable and open the file
    ofstream output_file;
    output_file.open("super.txt");
    // Write something to the file
    string name = "Batman";
    output_file << "My favorite superhero is " << name << endl;
    // Close the file once done
    output_file.close();
    // Declare the variable and open the file
    ifstream input_file;
    input_file.open("super.txt");
    // Read from the file
    string text;
    getline(input_file, text);
    cout << text << endl;
    // Close the file once done
    input_file.close();
    return 0;
}

Output:

My favorite superhero is Batman

The most important line in the above code is line 23.

getline(input_file, text);

This reads the entire line from the file. If instead we use the >> operator, then only the first word will be read ("My").


You can also use the getline() function with cin, like so:

getline(cin, variable_name);

In general, the first argument of the getline() function is any input stream, and the second argument is where you want the input to be stored.

getline() is also useful when you expect spaces in the input. For example, if you wanted to ask the user for the name of his favorite superhero, and you to allow the user to type Captain America as input (which has spaces in between the words), then using cin won’t read both the words. You should use getline() function instead.

Summary

In the last few exercises you learnt about:

  • sort - how to sort arrays and vectors, how to create your own comparison function to sort using a different criteria
  • file handling - how to open / close files, how to read / write from a file
  • getline - how to take input with spaces between words using the getline() function

Congratulations on making it till here! Now you are going to use your C++ skills and expertise for a really cool project where you will uncover secret messages!


© 2016-2022. All rights reserved.