Wednesday, 28 March 2012

Using stdin & stdout in C & C++


Normally if I wanted to send some data to the screen (the console or stdout), I'd use the printf function. Here's an example.

printf("There are %d polar bears outside your window.", BearCount);

It works great. And if I wanted to send the same information to a file, I would use the fprintf function. It works the same way except you must specify a file to use. Such as:

// Declare pointer to the file.
FILE* pFileHandle;

// Saves the file in the EXE folder.
char Filename[] = "MyFile.txt";

// Open file for writing.
pFileHandle = fopen(Filename, "w");

// Write data to file.
fprintf(pFileHandle , "("There really are %d polar bears outside your window.\n\n", BearCount);

// Close the file.
int iReturn = 0;
iReturn = fclose(pFileHandle);

What if I wanted to send the data to the screen or a file or both? While the standard I/O library creates a type FILE for handling files, it also creates the objects stdin and stdout. I can use the same fprintf function in both cases and write code to change the value of pFileHandle.

For a file,

pFileHandle = fopen(…

but for the screen use:

pFileHandle = stdout;

fprintf(pFileHandle , "Print some data to a text file.\n\n");

OR

fprintf(stdout, "Print some data to stdout.\n\n");

The same principle applies to reading data from a file or from the keyboard (i.e., stdin). I can use the fgets function for either.

From a file with,

fgets(Text, num, pFileHandle);

or from the standard input:

fgets(Text, num, stdin);

Data to a maximum length of num is stored in the character array Text.

The reason for doing this should be obvious. You can easily switch between a file or standard I/O without repeating your code.
 
Test Code.

I tested the functions in Visual C++ 2010 as an console application.

// The standard library includes the system function.
#include <cstdlib>

// C++ standard I/O library.
#include <cstdio>

// Function prototypes.
int DataOut(FILE* pFile);
int DataIn(FILE* pFile, char* text);

// Max length of text input.
const int MAXLEN = 80;

int main()
{
     // Using stdin & stdout in C & C++
    
     // Header.
     printf("Using stdin & stdout instead of a File\n\n\n");

     // Output.
     printf("***** OUTPUT *****\n\n");

     // Declare pointer to the file.
     FILE* pFileHandle;

     // Saves the file in the EXE folder.
     char Filename[] = "MyFile.txt";

     // Open file.
     pFileHandle = fopen(Filename, "w");

     // Write data to file.
     DataOut(pFileHandle);

     // Close the file.
     int iReturn = 0;
     iReturn = fclose(pFileHandle);

     // Do the same but send to stdout.
     DataOut(stdout);
     printf("\n\n");

     // Input.
     printf("***** INPUT *****\n\n");

     // Declarations.
     char readline[MAXLEN];

     // Open file.
     pFileHandle = fopen(Filename, "r");
     // Get data.
     DataIn(pFileHandle, readline);
     // Close the file.
     iReturn = fclose(pFileHandle);
     printf("From the file: %s\n", readline);
 
     printf("Input with fgets: ");
     // Get data.
     pFileHandle = stdin;
     DataIn(pFileHandle, readline);
     // OR DataIn(stdin, readline);
     printf("Your input: %s\n", readline);

     // Keep console window open.
     system("pause");

     // Return some value.
     return 0;
} // end main

int DataOut(FILE* pFile)
{
     // Code to send data to file or screen.
     fprintf(pFile, "Print some data to a text file or to the screen.\n\n");

     return 0;
}
int DataIn(FILE* pFile, char* text)
{
     // Code to send data to file or screen.
     fgets(text, MAXLEN, pFile);

     return 0;
}


Output.
 


Tuesday, 27 March 2012

The fprintf Function in C & C++


You can open a text or binary file with fopen and close it with fclose. (See here.) The fprintf function allows you to “print” data to a text file. It is similar to the printf function except the output goes to a file instead of the standard output.

A note on text files versus binary files. If you open a text file with an editor program, chances are you can read and make some sense of what’s there. Not so with a binary file. The binary file is raw data in the way variables stored in memory are raw data—binary data. But text files store binary data as well, but along the way, it’s converted to a human readable form using an ASCII table or Unicode character set. So while you may write “Hello World” to a text file and see it as such, it is being converted to some binary code.

Back to the fprintf function. The same code explains it.

Test Code.

I tested the functions in Visual C++ 2010 as an console application.

// The standard library includes the system function.
#include <cstdlib>

// C++ standard I/O library.
#include <cstdio>

int main()
{
     // Header.
     printf("\"Print\" Data To A Text File\n\n");

     // Pointer to the file.
     FILE* pFileHandle;

     // Puts the file in the project path.
     char Filename[] = "MyFile.txt";

     // Version 1.
     // w attribute for writing to the file.
     // If the file does not exist, it is created.
     // Any existing file content is overwritten.
     printf("File attribute: w - (over) write\n");
     pFileHandle = fopen(Filename, "w");

     // Write data to file.
     fprintf(pFileHandle , "\"Print\" Data To A Text File\n\n");
     fprintf(pFileHandle , "Writing some data to a text file.\n");
     fprintf(pFileHandle , "Any existing data in the file is lost.\n");

     // Close the file.
     int iReturn = 0;
     iReturn = fclose(pFileHandle);

     // Version 2.
     // a attribute for appending to the file.
     // If the file does not exist, it is created.
     // Any existing file content remains.
     printf("File attribute: a - appending\n");
     pFileHandle = fopen(Filename, "a");
     // Write data to file.
     fprintf(pFileHandle , "With appending mode, text is added to the file.\n");

     // Close the file.
     iReturn = fclose(pFileHandle);

     // Version 3.
     // What happens when you try to write data to a file opened for reading.
     printf("File attribute: r - reading\n");
     pFileHandle = fopen(Filename, "r");
     // Write data to file.
     fprintf(pFileHandle , "With reading mode, text isn't added to the file.\n");
     // There is no run-time error or compile error.

     // Close the file.
     iReturn = fclose(pFileHandle);

     // Keep console window open.
     system("pause");

     // Return some value.
     return 0;
} // end main


Text File.


Monday, 26 March 2012

A Common Error In C & C++


In C and C++ there’s a difference between the = assignment operator and the == logical equality operator. In many other languages, the equal sign is used in both situations; therefore, it’s easy to use = when you want to use ==.

You compiler won’t tap you on the shoulder to tell you made a mistake. It will happily chug along. There is no syntax error. The problem happens when you run the program. Besides, assigning the value to the variable, I tested some code to see what would happen.

Take this scenario.

     int a = 0;
     if (a = 1){…

First the program will assign 1 to a then it will evaluate the expression a as being non-zero (i.e., not false) and execute any code for the true condition.

This code

     if (a = 0){…

assigns zero to a and results in a false condition.

Similar events happen with the do and while loops.

How about a for loop like this?

     for (i = 0; a = i; ++i) {…

Since a equals i equals 0, it’s false and the for loop doesn’t execute any code under its control.

On the other hand, this code,

     for (i = 1; a = i; ++i) {…

creates an infinite loop. Be ready to hit break.

It’s the easiest mistake to make in C and C++ especially if you’re working with other languages at the same time.

Sunday, 25 March 2012

Modulus With Negative Numbers in C & C++


What it is correct answer when calculating the modulus of two numbers when one of the numbers is negative? When it comes to computers, the answer is: it depends.

The starting point is basic division of integers. Take a dividend, a, and divide it by the divisor, b, to get some result that is a quotient, q, and a remainder, r, if any. The modulus of a and b is the remainder, r. This division theorem works for all numbers that are integers, provided b is not zero.

 
If the a and b have the same sign (both positive or both negative), the quotient is positive. If their signs are opposite (one negative, one positive), the quotient is negative. What about the modulus? It’s easy to think the same process applies, but does it? No.

To calculate r, use the division equation for known values of a, b and q.

The following code in Visual C++ 2010 shows the four different possibilities pos+/neg- values for a and b.

 // Header.
printf("Modulus With Negative Numbers\n\n");
printf("a x b = q + r OR b x q + r = a\n\n");

int a = 7;
int b = 2;
printf("a = %d, b = %d \n", a, b);
printf("q: %d / %d = %d \n", a, b, a / b);
printf("r: %d mod %d = %d \n", a, b, a % b);
// 2 x 3 + 1 = 7
printf("%d x %d + %d = %d \n\n", b, a / b, a % b, a);

a = -7;
b = 2;
printf("a = %d, b = %d \n", a, b);
printf("q: %d / %d = %d \n", a, b, a / b);
printf("r: %d mod %d = %d \n", a, b, a % b);
// 2 x -3 - 1 = -7
printf("%d x %d + %d = %d \n\n", b, a / b, a % b, a);

a = 7;
b = -2;
printf("a = %d, b = %d \n", a, b);
printf("q: %d / %d = %d \n", a, b, a / b);
printf("r: %d mod %d = %d \n", a, b, a % b);
// -2 x -3 + 1 = 7
printf("%d x %d + %d = %d \n\n", b, a / b, a % b, a);

a = -7;
b = -2;
printf("a = %d, b = %d \n", a, b);
printf("q: %d / %d = %d \n", a, b, a / b);
printf("r: %d mod %d = %d \n", a, b, a % b);
// -2 x 3 - 1 = -7
printf("%d x %d + %d = %d \n\n", b, a / b, a % b, a);

Output.



You will get the same results in Visual Basic.

When it comes to using the modulus operator, test it with a range of expected parameters to make sure it gives the result you expect and want. Not all versions of C or C++ or other languages behave the same. If all else fails, create your own modulus function to work the way you want.

Saturday, 24 March 2012

The fopen and fclose Functions in C & C++


The cstdio library provides two functions for opening and closing a text file: fopen, fclose. Both functions use a FILE type pointer variable. The FILE type is defined in the library.

The fopen function requires a filename and a tag to specify the mode of access (read, write, append etc.) It returns a handle for accessing the file. The fclose function closes the file associated with the handle.

The first step is to create a pointer of the FILE type.

FILE * pFileHandle;

You open a text file for reading with this code:

pFileHandle = fopen("Filename", "r");

If the file does not exist, the functions returns NULL, otherwise it holds a handle for the opened file.

The file mode, “w” opens a file for writing. If the file does not exist, it is created. If the file exists, any existing data is overwritten.

pFileHandle = fopen("Filename", "w");

Finally, you can use the “a’ tag to append to a file. If the file does not exist, it is created. If the file exists, data is added to the end of the file.

pFileHandle = fopen("Filename", "a");

While it’s possible to close a file this way,

fclose(pFileHandle);

You should confirm the close function worked by analyzing the return value such as:

int iReturn = 0;
iReturn = fclose(pFileHandle);

If the return value is EOF, there was an error closing the file, otherwise the file was closed.

 
Test Code.

I tested the functions in Visual C++ 2010 as an console application.

// The standard library includes the system function.
#include <cstdlib>

// C++ standard I/O library.
#include <cstdio>

// C++ math library.
#include <cmath>

int main()
{
     // Header.
     printf("File Open, File Close.\n");
     printf("For text files.\n\n");

     // Pointer to the file.
     FILE* pFileHandle;

     // Puts the file in the project path.
     char Filename[] = "MyFile.txt";

     // Version 1.
     // r attribute for reading the file.
     // Fails to open if the file does not exist.
     printf("File attribute: r\n");
     pFileHandle = fopen(Filename, "r");
     if (pFileHandle != NULL)
           printf("File exists.\n");
     else
           printf("File doesn't exist.\n");
     printf("File Handle: %X \n\n", pFileHandle);

     // Version 2.
     // w attribute for writing to the file.
     // If the file does not exist, it is created.
     // Any existing file content is overwritten.
     printf("File attribute: w\n");
     pFileHandle = fopen(Filename, "w");
     if (pFileHandle != NULL)
           printf("File exists.\n");
     else
          printf("File doesn't exist.\n");
     printf("File Handle: %X \n\n", pFileHandle);

     // Version 3.
     // a attribute for appending to the file.
     // If the file does not exist, it is created.
     // Any existing file content remains.
     printf("File attribute: a\n");
     pFileHandle = fopen(Filename, "a");
     if (pFileHandle != NULL)
           printf("File exists.\n");
     else
           printf("File doesn't exist.\n");
     printf("File Handle: %X \n\n", pFileHandle);

     // Close the file.
     int iReturn = 0;
     iReturn = fclose(pFileHandle);
     // iReturn = 0 or false, means success closing the file.
     // iReturn = EOF means an error.
     if (iReturn == EOF)
           printf("Error closing the file.\n");
     else
           printf("File closed.\n");
     printf("File Handle: %X \n\n", pFileHandle);

     // Return some value.
     return 0;
} // end main


Output.

Friday, 23 March 2012

Using XOR To Encrypt Message


The XOR logic operator provides a convenient way to encrypt a message. By encrypt I refer to the technique where a letter of a readable message is substituted with another letter to make the encrypted message unreadable. At least at first glance.

The basic algorithm to encrypt a message is

message letter XOR key letter = encrypted letter

and to decrypt it’s:

encrypted letter XOR key letter = message letter.

Using the XOR operator with the same key results in symmetry for encrypting and decrypting. To understand that, take a closer look at what happens at the bit level.

I want to encrypt the letter A with the key letter of K.

A is 0x41 or 0100 0001 and K is 0x4B or 0100 1011.

A    0100 0001
K    0100 1011

XOR  0000 1010

So my encrypted letter is 0x0A.  Given that value and my key of K, I can run the same process to get the message back.

Ct   0000 1010
K    0100 1011

XOR  0100 0001

Why does it work? Look at the four possibilities:

A xor  K  = Ct xor K  = A
1      1    0      1    1
1      0    1      0    1
0      1    1      1    0
0      0    0      0    0

For each of the four possibilities, using XOR with the same key value brings you back to the original message.

Here is some sample code in C/C++.

// The standard library includes the system function.
#include <cstdlib>

int main()
{
     printf("Encrypt Message Using XOR\n\n");
     char msg = 'A';
     char key = 'K';
     char crypto;

     // Encipher.
     crypto = msg ^ key;
     printf("XOR of msg (%X) and key (%X) results in %X.\n\n", msg, key, crypto);

     // Decipher.
     msg = crypto ^ key;
     printf("XOR of crypto (%X) and key (%X) results in %X.\n\n", crypto, key, msg);
    

     // Keep console window open.
     system("pause");

     // Return some value.
     return 0;
} // end main

Output.