Month: May 2014

Flow of Control in C++

Branching control structures are used when we want the machine to choose an alternative based on a binary true / false assertion. If the statement is true, the computer executes an action. Alternatively, if the statement is false, it may execute a different action. The branching control structure depends on the bool data type; all branching statements are conditioned upon an assertion that ultimately evaluates to the Boolean value of either true or false.

We declare variables of type bool as we declare variables of other types, by writing the name of the data type and then the variable name.

#include <iostream>

using namespace std;

int main(void){

    bool a = true;
    bool b = false;

    cout  <<  "bool a is "  <<  a  <<  endl;
    cout  <<  "bool b is "  <<  b  <<  endl;

    return 0;

}

Note that unlike in regular C, in C++ bool is a fundamental data type. As in C, false corresponds to 0 and true corresponds to a non-zero value, typically 1.

Boolean expressions are made up of logical values and operands. Every logical expression ultimately evaluates to either true or false. Relational operators enables us to compare two mathematical expressions and derive a logical value from it.

#include <iostream>

using namespace std;

int main(void){

    int x,y;
    bool returnValue;    

    cout << "Enter a number: ";
    
    cin >> x;

    cout << "Enter another number: ";

    cin >> y;

    returnValue =  x > y;

    cout << x << " > " << y << " : " << returnValue << endl;

    returnValue = x < y;

    cout << x << " < " << y << " : " << returnValue << endl;

    return 0;

}

The fundamental control structure that allows branches in the flow of control is the if statement. By using the if statement, we can ask a question in the form of a logical assertion and choose a course of action depending on how the assertion is evaluated. The if statement consists of the if keyword followed by a logical expression contained in parentheses, follow by the statement or statement block to be conditionally executed. Optionally, we can follow this statement or statement block with the keyword else, followed by a statement or statement block to be executed if the expression evaluated to false.

#include <iostream>

using namespace std;

int main(void){

    bool trueVal = true;

    if(trueVal){
        cout << "This statement will be displayed." << endl;
    } else {
        cout << "This statement will not be displayed." << endl;
    }

    if(trueVal==0){
        cout << "This statement will not be displayed." << endl;
    } else {
        cout << "But this one will, as Boolean true does not equal 0." << endl;
    }

    return 0;

}

Compound statements must be enclosed in curly braces. As a matter of style, it is considered best practice to include any statements whose execution is conditional in curly braces, even if there is only one statement.

Be aware that the else portion of an if-else statement is optional.

#include <iostream>

using namespace std;

int main(void){

    bool val;

    int a, b;

    a = 404;
    b = 8086;

    if(a!=b){
        cout << a << " does not equal " << b << endl;
    }

    if(a<b){
        cout << a << " is less than " << b << endl;
    }
    

    return 0;

}

It is possible to place and if statement within another if statement. By nesting our if statements, we can implement complex logic that enables our computer to deal in a nuanced manner with varying input. Nested if statements enable us to create multiway branches, were the flow of execution has more than two possible paths.

#include <iostream>

using namespace std;

int main(void){

    int temp = 40;

    if(temp > 20){
        if(temp < 33){
            cout << "Let's go for a hike " << endl;
        } else {
            cout << "Let's go swimming " << endl;
        }
    } else {
        if(temp > 0){
            cout << "Let's stay inside " << endl;
        } else {
            cout << "Let's go skiing " << endl;
        }
    }


    return 0;

}

Note that is important to consider human readability as well when designing branching structures.

 

 

 

 

 

Brief Look at File Input and Output in C++

Input and output is oriented around three classes: the istream class for input, the ostream class for output, and the iostream class for input/output. As of the current standard, istream and ostream are included in the iostream class. This class provides use with three predefined variables – cin, for console input, cout, for console output, and cerr, for standard error.

The file version of the stream classes are included in the fstream header file. The input file variable is ifstream and the output file variable is ostream, meaning that the ifstream is used to read data from a file and the ofstream is used to write data to a file. We use the member function open() to open a file for reading or writing. We pass the open() function the path of the file to open.

#include <iostream>
#include <fstream>

using namespace std;

int main(void){

    ofstream writeFile;
    //create a file named Example.txt
    //int the current directory
    writeFile.open("Example.txt");
    //close the file stream
    writeFile.close();

    return 0;

}

Note that we should tell the I/O system we are done with the file via the close() member function.

We can write to and read from a file using the same statements we have been using to read from and write to cin and cout.

#include <iostream>
#include <fstream>

using namespace std;

int main(void){

    ofstream writeFile;
    writeFile.open("test2.txt");
    
    //write a line to the file
    writeFile << "Saluton Mundo!" << endl;    

    writeFile.close();

    return 0;    

}

Reading from a file is a bit trickier. We need to read the data from the file into a storage unit, such as a variable. If we know the type of data that is stored in the file this is easy to do.

#include <iostream>
#include <fstream>
#include <string>

using namespace std;

int main(void){

    int score1, score2, score3;
    //dont' forget to include
    //string header file
    string s;

    ofstream write;
    ifstream read;

    //write to file
    write.open("test3.txt");

    write << "Scores " << 85 << " " << 73 << " " << 99 << endl;

    write.close();

    //read from file
    read.open("test3.txt");

    read >> s >> score1 >> score2 >> score3;

    cout << s << " " << score1 << " " << score2 << " " << score3 << " ";
    cout << "avg. " << (score1 + score2 + score3) / 3.0 << endl;

read.close();

    return 0;    

}

We can also read from the file into a char array that acts a buffer for the data. We do this using the read() member function, which accepts two arguments, a pointer to the char array buffer and the number of characters to be read into the buffer.

#include <iostream>
#include <fstream>

using namespace std;


int main(void){

    const int buffer_size = 50;

    char buffer[buffer_size];

    ifstream read;
    ofstream write;

    write.open("test4.txt");


    write << "If mice could swim they would float with the tide and play with the fish down by the seaside. ";
    write << "The cats on the shore would quickly agree."    << endl;

    write.close();

    read.open("test4.txt");

    read.read(buffer, buffer_size-1);

    buffer[buffer_size-1] = '';

    cout << buffer;

    read.close();

    return 0;

}

When opening files for read/write, we should check to make sure that the file was opened. We can use the fail() member function to see if ifstream or ofstream is in the fail state.

#include <iostream>
#include <fstream>

using namespace std;

int main(void){

    
    ifstream read;
    read.open("doesnotexist.txt");

    if(read.fail()){
        cout << "Could not open the file." << endl;
        return 1;
    }

    return 0;

}

There’s really a lot more to file input and output than this; we’ll be looking more deeply at the subject in later posts.

As always, please take a gander at my book on C at http://www.amazon.com/Big-Als-C-Standard-ebook/dp/B00A4JGE0M/