Sunday, January 13, 2013

Reading from Console in ANSI C

The ANSI C standard I/O library (stdio.h) provides us with 3 powerful functions for reading data from STDIN (the stream used for the console):
-Reading a character: getchar
-Reading formatted input: scanf
-Reading an entire line: gets

Here's a short example on how you can use any of these functions to read a string:
#include<stdio.h>

int main(void)
{
    const int LENGTH = 100;

    //The variable where the string will be stored
    char myString[LENGTH];
    //Iterator for reading with getchar
    int i;

    //Reading with getchar
    puts("Reading the string using getchar: ");
    for(i=0; i<(LENGTH-1); i++)
    {
        myString[i] = getchar();
        //Stops reading when the user presses ENTER
        if(myString[i]=='\n')
        {
            //Adds the null terminator
            myString[i+1]='\0';
            break;
        }
    }
    puts(myString);

    //Reading with gets
    puts("Reading the string using gets: ");
    gets(myString);
    puts(myString);

    //Reading with scanf
    puts("Reading the string using scanf: ");
    scanf("%s",myString);
    puts(myString);

    return 0;
}
If you don't know what puts does, you may like to read this first.

When to use getchar?
getchar is a great function to be used when you want to limit the user input or you want to validate it (or you just want to process the input character by character). Here are some examples:
-You built a console menu, just like the one in here, and you want to read only one character
-You want to stop the user input if a certain character is encountered
#include<stdio.h>

int main(void)
{
    const int LENGTH = 200;

    char myText[LENGTH];
    int i = 0;
    //The characters are put into the string until . in encountered
    do
    {
        myText[i] = getchar();
        i++;
    }while(myText[i-1]!='.');
    //Adding the null terminator
    myText[i+1] = '\0';
    puts(myText);
    return 0;
}
-You want to make sure that a buffer overflow doesn't happen :-) . We will speak more about this when we get to gets.
#include<stdio.h>

int main(void)
{
    const int LENGTH = 5;

    char pinNumber[LENGTH];
    int i;
    //Only 4 characters are read
    for(i=0; i<(LENGTH-1); i++)
    {
        pinNumber[i] = getchar();
    }
    //Adding the null terminator
    pinNumber[LENGTH-1] = '\0';
    puts(pinNumber);
    return 0;
}
-You want to extract only certain characters from the user's input:
#include<stdio.h>

int main(void)
{
    const int LENGTH = 5;

    char pinNumber[LENGTH];
    int i = 0;
    char buffer;
    //Only 4 characters are read and they should be digits!
    while( (i<(LENGTH-1)) )
    {
        buffer=getchar();
        if( (buffer>='0') && (buffer<='9') )
        {
            pinNumber[i] = buffer;
            i++;
        }
    }
    //Adding the null terminator
    pinNumber[LENGTH-1] = '\0';
    puts(pinNumber);
    return 0;
}
/*Example Input:
  The b1rd 1s th3 w0rd.
  Output
  1130
*/
TIP : Don't forget to add the null terminator to your string! If you don't know what a null terminator is, read this.

When to use scanf?
scanf should be used when you are dealing with number or otherwise other forms of formatted input. If you do not know exactly what formatted input and formatted strings are, see this. Here are some examples:
#include<stdio.h>

int main(void)
{
   //Integers
   int intData1,intData2;
   //Real
   double realData, realData2;
   //Characters
   char charData, charData2;
   //Strings
   char stringData[10], stringData2[10];

   //Read a integer value using the decimal base
   puts("Write a integer: ");
   scanf("%d",&intData1);
   //Read a integer value using the hexadecimal base
   puts("Write a integer in hexadecimal: ");
   scanf("%x",&intData2);
   //Read a real value
   puts("Write a real number: ");
   scanf("%lf",&realData);
   //Discards the last character, before reading a char with scanf
   getchar();
   //Read a character
   puts("Write a character: ");
   scanf("%c",&charData);
   //Read a string. A string is a pointer and you don't need the & operator
   puts("Write a string: ");
   scanf("%s",stringData);
   //Reading multiple values
   puts("Write a string, a real number and a character: ");
   scanf("%s %lf %c",stringData2,&realData2, &charData2);

   printf("Integer data: %d %x\n"
          "Real data: %lf\n"
          "Char data: %c\n"
          "String data: %s\n"
          "Multiple values: %s %lf %c",
          intData1, intData2, realData,charData, stringData,
          stringData2, realData2, charData2);

   return 0;
}
/*Example session:
Write a integer:
12
Write a integer in hexadecimal:
f3
Write a real number:
32.3
Write a character:
x
Write a string:
mystr
Write a string, a real number and a character:
mystr
44.8
c
Integer data: 12 f3
Real data: 32.300000
Char data: x
String data: mystr
Multiple values: mystr2 44.800000 c
*/
There are some certain particularities to scanf:
TIP : Formatted data should be reffered through a pointer (that's why the & operator is used). String are pointers by default and the & operator should not be used on them.
TIP :  You can avoid a buffer overflow, by specifying the maximum size of input when reading a string. In the example below, the limit is 4 characters + the automatically added null terminator:
#include<stdio.h>

int main(void)
{
    char myString[5];
    puts("Input a string: ");
    scanf("%4s", myString);
    puts(myString);
    puts("No buffer overflow");
    return 0;
}
/*Session
Input a string:
ThisIsGroundControlToMajorTom
This
No buffer overflow
*/
TIP :  If you read a character using scanf and before that you read a string or a number, you may observe that the character reading may be "skipped". This happens because the input buffer contains a newline character that remained from the previous reading (if you watch this with the debugger you shall see that your character shall be equal to 10 which is the equivalent of newline). Use getchar calls to discard extra characters from the input buffer.
PITFALL :  If you read a string with scanf and it encounters a whitespace character, the function will consider it as a terminator. Use scanf to read words, not sentences :-)

When to use gets?
The main purpose of gets is to read strings that contain whitespace. Here's an example:
#include<stdio.h>

int main(void)
{
    const int LENGTH = 200;

    char myString1[LENGTH];
    char myString2[LENGTH];

    puts("Input a string: ");
    gets(myString1);

    puts("Input the same string again: ");
    scanf("%199s",myString2);

    puts("String read with gets: ");
    puts(myString1);
    puts("String read with scanf: ");
    puts(myString2);

    return 0;
}
/*Session
Input a string:
The bird is the word
Input the same string again:
The bird is the word
String read with gets:
The bird is the word
String read with scanf:
The
 */
PITFALL:Unfortunately gets has many inherent problems related to buffer overflow, since you cannot specify the maximum number of character to read. This article explains it in more detail.
TIP: Just like in scanf, a null terminator is added at the end of the string replacing the newline character.
TIP: A safer alternative to gets is fgets. Here's how you can replace gets with fgets in the program above:
#include<stdio.h>

int main(void)
{
    const int LENGTH = 200;

    char myString1[LENGTH];
    char myString2[LENGTH];

    puts("Input a string: ");
    fgets(myString1, LENGTH-1, stdin);

    puts("Input the same string again: ");
    scanf("%199s",myString2);

    puts("String read with gets: ");
    puts(myString1);
    puts("String read with scanf: ");
    puts(myString2);

    return 0;
}
Question: In which situations do you use gets, in which situations scanf and in which situations getchar?

References:
http://www.cplusplus.com/reference/cstdio/
http://c-faq.com/stdio/index.html
http://faq.cprogramming.com/cgi-bin/smartfaq.cgi

Tuesday, January 8, 2013

How to Print to Console in ANSI C

The ANSI C standard I/O library (stdio.h) provides us with 3 powerful functions for outputting characters to STDOUT (the stream used for the console):
-Printing a character:  putchar
-Printing a string : puts
-Printing a formatted string : printf

A formatted string is a dynamical string that is built on the go. Here's an example:
#include<stdio.h>

int main(void)
{
    int myInt = 42;
    unsigned int myUint = 0xFFU;
    char myChar = 'a';
    double myDouble = 3.42;
    char myString[20] = "myString";

    printf("Formatted string with the values: %d, %x, %c, %lf and %s.",
            myInt, myUint, myChar, myDouble, myString);

    return 0;
}
/*Output
Formatted string with the values:: 42, ff, a, 3.420000 and myString.
 */
You can read more about formatted strings in this article.

There is also vprintf, which allows to print arguments received as a va_list, be we shall not go into details since is not very used.

Here's a short example on how to use these three functions to print a string:
#include<stdio.h>
#include<string.h>

int main(void)
{
    char myString[21] = "The bird is the word.";
    //Computing the length of the string for putchar
    int length = strlen(myString);
    //Iterator used for putchar
    int i = 0;

    //Outputting the string using printf
    printf("%s\n",myString);
    //Outputting the string using puts
    puts(myString);
    //Outputting the string using putchar
    for(i = 0; i<length; i++)
    {
        putchar(myString[i]);
    }
    putchar('\n');

    return 0;
}
/*Output
The bird is the word.
The bird is the word.
The bird is the word.
 */
The program above prints the string myString. As you can see you can print it as a formatted string using printf, as a normal string using puts and character by character using putchar.

TIP 1: puts automatically adds a newline character to the string. If you use printf or putchar you will have to specify the newline yourself.
TIP 2: To print a string using puts, you will probably need to know the length of the string. This can be achieved by using strlen from string.h.
TIP 3: printf returns the number of characters that were printed if successful. Otherwise returns a negative value.
TIP 4: puts returns a non-negative value if it was successful. Otherwise it returns EOF.
TIP 5: putchar returns the written character if it was successful. Otherwise it returns EOF.
TIP 6: You can also use putchar in the following fashion:
#include<stdio.h>

int main(void)
{
    //Outputs a character specified by character
    putchar('w');
    //Outputs a character specified by its ASCII code in decimal
    putchar(119);
    //Outputs a character specified by its ASCII code in hexadecimal
    putchar(0x77);
    //Outputs a character specified by its ASCII code in octal
    putchar(0167);

    return 0;
}
/*Output
wwww
 */

A little bit about performance:

Speaking in terms of performance, printing is fastest when using puts.
Number of charactersputs (sec)printf (sec)putchar (sec)
100.010.0580.017
1000.0540.2710.073
10000.1050.7820.164
100000.5041.2640.961
1000005.1265.7099.428
The table above represents a benchmark I took using gcc on Linux. By no means, the data is 100% percent accurate since it depends on the hardware configuration and the other processes running at that time, but it can offer a little overview.

If you want to see my test, click here.

Question: In which situations do you use printf, in which putchar and in which puts?

References:
http://www.songho.ca/misc/timer/timer.html
http://www.cplusplus.com/reference/cstdio/
http://pubs.opengroup.org/onlinepubs/7908799/xsh/stdio.h.html

Friday, January 4, 2013

Using sizeof to Determine the Size of a Data Type in ANSI C

The size of an ANSI C data type is dependent on the compiler.  However it can be easily determined by using the sizeof operator.

Here's a  example on how to do it:
#include<stdio.h>

typedef struct
{
    int  field1;
    long field2;
    char field3[30];
}ExampleStructure;

typedef union
{
    int field1;
    double field2;
}ExampleUnion;

typedef enum
{
    enum1,
    enum2,
    enum3
}ExampleEnum;

int main(void)
{
    printf("char          : %d bytes\n"
           "short int     : %d bytes\n"
           "int           : %d bytes\n"
           "long int      : %d bytes\n"
           "long long int : %d bytes\n"
           "float         : %d bytes\n"
           "double        : %d bytes\n"
           "long double   : %d bytes\n"
           "ExampleStruct : %d bytes\n"
           "ExampleUnion  : %d bytes\n"
           "ExampleEnum   : %d bytes\n"
           "void*         : %d bytes\n"
           "char*         : %d bytes\n"
           "short int*    : %d bytes\n"
           "int*          : %d bytes\n"
           "long int*     : %d bytes\n"
           "long long int*: %d bytes\n"
           "float*        : %d bytes\n"
           "double*       : %d bytes\n"
           "long double*  : %d bytes\n"
           "ExampleStruct*: %d bytes\n"
           "ExampleUnion* : %d bytes\n"
           "ExampleEnum*  : %d bytes\n",
           sizeof(char),
           sizeof(short),
           sizeof(int),
           sizeof(long),
           sizeof(long long),
           sizeof(float),
           sizeof(double),
           sizeof(long double),
           sizeof(ExampleStructure),
           sizeof(ExampleUnion),
           sizeof(ExampleEnum),
           sizeof(void*),
           sizeof(char*),
           sizeof(short*),
           sizeof(int*),
           sizeof(long*),
           sizeof(long long*),
           sizeof(float*),
           sizeof(double*),
           sizeof(long double*),
           sizeof(ExampleStructure*),
           sizeof(ExampleUnion*),
           sizeof(ExampleEnum*));
    return 0;
}
/*Output
char          : 1 bytes
short int     : 2 bytes
int           : 4 bytes
long int      : 4 bytes
long long int : 8 bytes
float         : 4 bytes
double        : 8 bytes
long double   : 12 bytes
ExampleStruct : 40 bytes
ExampleUnion  : 8 bytes
ExampleEnum   : 4 bytes
void*         : 4 bytes
char*         : 4 bytes
short int*    : 4 bytes
int*          : 4 bytes
long int*     : 4 bytes
long long int*: 4 bytes
float*        : 4 bytes
double*       : 4 bytes
long double*  : 4 bytes
ExampleStruct*: 4 bytes
ExampleUnion* : 4 bytes
ExampleEnum*  : 4 bytes
 */
The program above calculates the size of each type and outputs it to console. The output was obtained using the gcc compiler. If you use other compiler, you might obtain different results.

TIP 1: The size of a structure is determined by the size of its members plus the padding bits. In our case we have 2 (field1) + 4 (field2) + 30 (field3) + 4 (padding) = 40 bytes. 
TIP 2: The size of an union is determined by the size of its largest member (in our case long field2). 
TIP 3: The size of an enumeration corresponds in most cases to the size of int.
TIP 4: All pointer types have the same size which usually corresponds to the size of int.
You can read more about the assumptions you can make when dealing with primitive data types here.

References:
Related Posts Plugin for WordPress, Blogger...