formatted output and printf

Upload: thajid-ibna-rouf-uday

Post on 03-Jun-2018

259 views

Category:

Documents


0 download

TRANSCRIPT

  • 8/12/2019 Formatted Output and Printf

    1/12

    Formatted Output and the printf function

    One of the most important and common tasks in virtually every program is the printing of output. Programs use

    output to request input from a user, to display status messages, and to inform the user of the results of

    computations that the program performs. For obvious reasons, the manner in which the program displays its

    output can have a profound effect on the usefulness and usability of a program. When a program prints its output

    in a neatly formatted fashion, the output is always easier to read and understand. As a result, being able to write

    programs easily that produce attractive output is an essential feature of most programming languages.

    C has a family of library functions that provide this capability. All of these functions reside in the stdiolibrary.

    Although the library contains several functions for printing formatted output, it is likely that you will only use two

    of them with any frequency. One, the printf(short for "print formatted") function, writes output to the computer

    monitor. The other, fprintf, writes output to a computer file. They work in almost exactly the same way, so

    learning how printfworks will give you (almost) all the information you need to use fprintf.

    Using printf to print messages

    To use the printffunction, you must first insure that you have included the stdio library in your program. You do

    this by placing the C preprocessor directive

    #include

    at the beginning of your program. If you are also including other libraries, you will have other #include

    directives; the order of these does not matter.

    When you actually use the printf function, that is, when you want your program to print something on the screen,

    you will place a callto the function in your source code. When we want a function to perform its task we say we

    "call" it, and a function call is a type of program statement. All function calls have the same basic format. The first

    part of the call is always the name of the function (in this case, printf). Following the function name is anargument listorparameter list. The terms "argument" and "parameter" are synonymous in computer

    programming. An argument list provides information for the function. In the same way that a mathematical

    function takes some input value, performs a transformation, and produces a result (output), functions in C

    typically require some input as well. For the printffunction, the argument list will provide the information that the

    function should print to the screen. We generally say that wepassarguments to a function.

    An argument list has a particular form as well. First, a pair of parentheses always encloses the list of arguments.

    Inside the parentheses, we separate multiple arguments from each other with a comma. Since a function call is a

    kind of statement, you will also need to follow the call with a semicolon, just after the closing parenthesis of the

    argument list. We can formalize a function call then as follows:function_name (argument1,argument2, ...);

    The "..." signifies that there may be more arguments. In fact, there may also be fewer arguments.

    Different functions require different kinds of input. Some functions need only one parameter, others may need

    many, and some do not need any parameters at all. In this last case, the argument list would simply be a pair of

    parentheses with nothing inside. In most cases, any given function needs a particular number of parameters. That

    is, we might have a function that requires three pieces of information to perform its task. Every time we call that

    function, we will need to provide exactly three parameters in its argument list. The printffunction is unusual,

  • 8/12/2019 Formatted Output and Printf

    2/12

    because the number of parameters it needs is variable. It always requires at least one argument, called the

    format string. Depending on what this argument contains, we may need to pass other parameters to printfas

    well.

    In C, a "string" is a sequence of one or more characters that the programmer intends to use as a unit (such as a

    word or sentence). The first program you saw printed a sentence, "Hello world," to the screen. The series of

    characters that forms this sentence is a string. To ensure that the compiler processes a string as a string, rather

    than as identifiers, we use a pair of double quotes around a string constant to show that it is a string. This is quite

    similar to using single quotes to indicate a character constant. It is important to remember that the single and

    double quotes are not interchangeable. Later, you will learn the difference between a one-character string, such

    as "a" and a single character, such as 'a'. For now, you must simply try to remember that they are different. The

    following mnemonic may help you remember when to use double quotes and when to use single quotes. A

    character is always just one character, while a string usually contains several characters. Thus, a character is

    usually "shorter" than a string. The single quote is also "shorter" than the double quote, so you use the "short" with

    the "short."

    In its simplest form, a format string is just a series of characters that you want to print to the screen. It will print

    exactly as it appears in the argument list, except that the double quotes will not appear. This is generally how youwould use printfto print a prompt to request that the user of a program enter some data. For example, if you

    wanted to ask a user to type a number, you might call printf as follows:

    printf ("Please type an integer then press Enter: ");

    When the computer executes this statement, the message will appear on the screen:

    Please type an integer then press Enter: |

    You will often use this simplest kind of format string when you want to display some sort of status message or

    explanation on the screen. For instance, if you wrote a program that you knew would take some time to perform

    a task, you would probably want to let the user know that the program was working and had not crashed. You

    might use printfto tell the user what the program is doing:

    printf ("Searching, please wait...");

    On the screen, you would see:

    Searching, please wait...|

    In both of the examples above, once the message has appeared, the cursor will remain at the end of the printed

    output. If you called printfagain, the next message would appear immediately after the first one. Usually, this wil

    not be what you want. Instead, you will want to print the next message on the next line of the screen, but you wil

    need to tell printfto do this; it will not happen automatically. You know that if you are typing that you press the

    Enter key to get from one line to the next, but, as a programmer, if you press the Enter key inside the double

    quotes of the format string, the cursor will go to the next line of your source code file. If you then type the double

  • 8/12/2019 Formatted Output and Printf

    3/12

    quote, closing parenthesis, and semicolon and then try to compile the program, the compiler will give you a

    syntax error. Usually, the error message will tell you that you have an "unterminated string constant." This is

    because the compiler expects to find the closing double quote on the same line as the opening double quote.

    More control using escape sequences

    Obviously, then, we need another way to tell printfto send the cursor to the next line after printing the rest of the

    characters in the format string. C uses escape sequenceswithin a format string to indicate when we want printfto print certain special characters, such as the character that the Enter key produces. The escape character for a

    newline(which sends the cursor to the beginning of the next line on the screen) is \n. The backslash is called the

    escape characterin this context and it indicates that the programmer wants to insert a special character into the

    format string. Without the backslash, printfwould simply print the 'n'. You might guess that the 'n' is an

    abbreviation for "newline." C provides several escape sequences, but only a few are common. Others that you

    might find useful appear in the following table:

    Escape sequenceAction

    \n prints a newline

    \b prints a backspace (backs up one character)

    \t prints a tab character

    \\ prints a backslash

    \" prints a double quote

    If we alter the second example above as follows:

    printf ("Searching, please wait...\n");

    the screen will appear as before, except that now the cursor will be on the next line. Furthermore, if the program

    contains another printf statement later on, the next output will be printed on that same next line.

    Searching, please wait...

    |

    Here are a few more examples of printfstatements that make use of escape sequences:

    printf ("\nName\tAddress\n");

    produces:

    Name Address

    |

    printf ("Joe's Diner\b");

    displays:

    Joe's Dine|

  • 8/12/2019 Formatted Output and Printf

    4/12

    printf ("Please type \"Yes\" or \"No\": ");

    prints:

    Please type "Yes" or "No": |

    Using printf to print values with format specifiers

    As you can see, escape sequences give us some ability to format output even when we use the simplest form or

    the printf function, but printfis actually much more powerful than we have seen. First, assume for a moment tha

    you have declared a variable in your program as follows:

    int number = 10;Now suppose that you want to prove to yourself that the variable numberreally does hold the value 10. You

    want to display the string "The value of number is 10" on the screen. You might try calling printfas follows:

    printf ("The value of number is number\n"); /* This won't work */

    Of course, because printfprints the format string exactly as it appears (except for the escape sequences), what

    you will see on the screen is:

    The value of number is number

    |

    The problem is that within the program's source code, we have only one way to refer to the variable number

    and that is by its name. The names of identifiers are made up of characters, so if we place a variable's name in a

    format string, printfwill simply print that name. Just as C solves the problem of displaying special characters

    within a format string through the use of escape sequences, it solves this problem using another special notation

    within the format string. Besides escape sequences, the format string argument can also containformat

    specifiers. A format specifier is a placeholder that performs two functions. First, it shows wherein the output to

    place an item not otherwise represented in the format string and it indicates howprintfshould represent the item

    The "item" is most often a variable, but it can also be a constant. In particular, format specifiers allow us to print

    the values of variables as well as printing their names.

    All format specifiers begin with a percent sign, just as all escape sequences begin with a backslash. What follows

    the percent sign tells at least what data type printfshould expect to print. It can also indicate exactly how the

    programmer wants printfto display it. Schematically, we can represent the syntax for a format specifier as

    follows:

    %[flags][width][.precision]type_character

    As usual, italics indicate placeholders for which a programmer must substitute a specific value. The square

    brackets that appear in this syntax template mean that the placeholders within are optional. They can appear or

  • 8/12/2019 Formatted Output and Printf

    5/12

    not, as the needs of the programmer dictate. The brackets themselves do not appear in the source program.

    Most of the time, format specifiers will not include any of the optional items. The options give the programmer

    precise control over the spacing of the output and even over how much of the output printfwill display. Thus,

    most often a format specifier will simply be a percent sign followed by a "type character." The type character is

    what tells printfwhat data type to print. The following table shows the most common type characters (several

    others exist):

    type character print formatd integer number printed in decimal (preceded by a minus sign if the number is negative)

    f floating point number (printed in the form dddd.dddddd)

    E floating point number (printed in scientific notation: d.dddEddd)

    g floating point number (printed either as f or E, depending on value and precision)

    x integer number printed in hexadecimal with lower case letters

    X integer number printed in hexadecimal with upper case letters

    c character

    s string

    For example, the format string "%d" indicates to printf that it should write an integer in base 10 format, whereas

    the format string "%s" tells printfto print a string. Notice that the format specifiers tell what kind of thing the

    programmer wants to display, but they do not tell what valueto print. That means that printf will need some

    additional information in the form of an additional argument. A format string can contain more than one format

    specifier and the format specifier(s) can appear in conjunction with other text, including escape sequences. Each

    format specifier that appears in the format string requires an additional argument in the argument list. The

    additional argument specifies what value printfshould substitute for the format specifier. For instance, the

    following call to printfwill display the value of our variable number:

    printf ("The value of number is %d\n", number);

    The value of number is 10

    |

    The two arguments to this call to printfcombine to tellthe function exactly what to write on the screen. What

    happens is that the printffunction actually takes apart the format string and checks each character before

    displaying it. Whenever it encounters the percent sign, it checks the next character. If the next character is a type

    character, printfretrieves the next argument in the argument list and prints its value. If the next character is notatype character, printf simply displays the percent sign. For example,

    printf ("The value of number is %q\n", number);

    will print:

    The value of number is %q

    |

  • 8/12/2019 Formatted Output and Printf

    6/12

    Although it is unlikely that you will ever really want to do so, you may be asking, "so what if I want to print

    something like '%d' on the screen." If printffinds the sequence %d in a format string, it will substitute a value for

    it. To print one of the format specifiers to the screen, then, you have to "trick" printf. The following call:

    printf ("The % \bd format specifier prints a base 10 number.\n");

    will display:

    The %d format specifier prints a base 10 number.

    |

    In the format string, a blank space follows the percent sign, not a type character, so printf will simply display the

    percent sign. It then displays the blank space (the next character in the format string), and then it displays the

    backspace character (specified with the escape sequence \b). This effectively erases the blank space. The next

    character in the format string is the letter 'd', which printfwrites in the place where it originally wrote the blank.

    We mentioned above that we can have more than one format specifier in a format string. If we do this, we will

    need one additional argument for each of the format specifiers. Furthermore, the arguments must appear in thesame orderas the format specifiers. Examine the following examples:

    printf ("The value of number, %d, multipled by 2, is %d.\n",

    number, number*2);

    prints:

    The value of number, 10, multiplied by 2, is 20.

    |

    As you can see from the previous example, the argument can be an expression such as number * 2 as well as a

    variable.

    printf ("The value of number, %d, multipled by 2, is %d.\n",

    number*2, number);

    displays:

    The value of number, 20, multiplied by 2, is 10.

    |

    In the preceding example, the order of the additional parameters is wrong, so the output is plainly nonsensical.

    You must remember that printfdoes not understand English, so it cannot determine which argument belongs

    with which format specifier. Only the order of the parameters matters. The printffunction substitutes the first of

    the additional arguments for the first format specifier, the second of the additional arguments for the second

    format specifier, and so on. Thus,

    printf ("%d + %d = %d\n", number, number*2, number + number*2);

    writes:

  • 8/12/2019 Formatted Output and Printf

    7/12

    10 + 20 = 30

    |

    Because printfuses the additional parameters to give it the values to substitute for the format specifiers, it is

    essential that, as a programmer, you supply enough parameters. For instance, if we rewrite the preceding

    example as follows so that we have three format specifiers in the format string, but only two additionalparameters:

    printf ("%d + %d = %d\n", number, number*2);

    printfwill print something bizarre on the screen. Since it has no value for the third format specifier, it will print a

    garbage value. We have no way to predict exactly what value it will display (it may even coincidentally be the

    right value!), but it would not be surprising to see output such as:

    10 + 20 = -4797

    |

    The moral of the story is that if you see strange output when you are using format specifiers, one of the first things

    you should check is the order and number of the additional arguments.

    You might also see unexpected output for one other reason. The type character in the format specifier

    determines completely how printfwill display a value. If you include a format specifier with a particular type

    character in your format string and then give an argument of a different data type, printfwill display the value of

    the argument using the syntax for values corresponding to the type character, not the syntax corresponding to the

    data type of the argument. For example,printf ("%d", 'a');

    will print:

    97|

    since the ASCII code for 'a' is 97.

    printf ("%f", 5);will display:

    5.000000|

    In each example, printfmakes an implicit type conversion of its argument to force it to agree with the data type

  • 8/12/2019 Formatted Output and Printf

    8/12

    that the type character specifies. In some special cases, you can use this automatic conversion to your advantage

    but most of the time, you will want to ensure that the data type of the argument matches the type character.

    More control using format specifier options

    The syntax template for a format specifier given above provides for several options. These options allow the

    programmer to control precisely how output will appear on the screen. The syntax template appears again here

    for easy reference:%[flags][width][.precision]type_character

    Again, the order of the options is just as important as the order of arguments to the printffunction. In other

    words, if you want to use multiple options, they must appear in the same order as they do in the syntax template.

    Field width specifiers

    Although the first option isflags, it is actually the least common, so we will leave its discussion for last. The

    widthoption is the option you will use most frequently. This option is often called afield width. We usually use

    field widths to line up columns of data to form tables on the screen. Printing things in tables makes output more

    readable. We can also use field widths for other reasons as well. Since they allow us to control exactly where a

    value will appear on a line of the screen, we can also use field widths when we want to "draw" with characters.

    The value that the format specifier indicates is sometimes called a "field" so the field width controls how many

    columns the field will occupy on the screen. The value that we substitute for the italicized widthin an actual

    format specifier can be one of two things. Most often, it will be an integer. For example, assume that your

    program contains a declaration for a character variable as follows:

    char digit = '2';

    If the body of the code contains the following statement:

    printf ("%3c\n", digit);

    what printf will display is:

    2

    |

    Notice that two blank spaces precede the digit '2'; this means the entire field (two blanks and one non-blank

    character) occupies three columns. In addition, notice that the blanks come beforethe digit. We call this right

    justification. Right justification implies that items on a single row of the screen will line up along the right margin.

    Thusm if we immediately make another call to printfas follows:printf ("%3c\n", digit+1);

    the screen will look like this:

    2

    3

    |

  • 8/12/2019 Formatted Output and Printf

    9/12

    The field width you specify is the minimum number of columns that output will occupy. If a complete

    representation of a value requires more columns, printfwill print the whole value, overriding the field width. For

    example, consider the following call to printf:

    printf ("%3f\n", 14.5);

    The field width specifier in this call is 3, but the value, 14.5 actually requires four columns (the decimal point

    requires a column as well as the digits. In this case, the display will be:

    14.5

    |

    If we alter the call:

    printf ("%3f\n%3f", 14.5, 3.2);

    printf writes:

    14.5

    3.2|

    Notice that because the field width was too small, the right justification fails; the two numbers do not line up

    along the right hand margin. A field width that requires fewer columns than the actual data value requires will

    always result in this failure.

    You may be wondering at this point how justification allows us to print tables. So far, we have only put one value

    on each line, but if we print several values before each newline, we can use field widths to force them to line up.

    Consider the following series of printfstatements:

    printf ("%10s%10s\n", "month", "day");

    printf ("%10d%10d\n", 1, 10);

    printf ("%10d%10d\n", 12, 2);

    What appears on the screen when these statements executes is a table:

    month day

    1 10

    12 2

    |

    Notice in particular that the field widths always start from the last column printed. At the beginning, the cursor is

    in the extreme upper left corner of the screen. The format string in the first printfstatement specifies that the

    function should print the string "month" using 10 columns. Since "month" only requires 5 columns, printf

    precedes the string with five blanks. At this point, the cursor will be in the eleventh column. The next format

    specifier requires printf to write the string "day", also using 10 columns. The string "day" takes up three columns,

    so printfmust precede it with seven blanks,starting from the current cursor position. In other words, the

    column count begins just after the last letter of the string "month".

  • 8/12/2019 Formatted Output and Printf

    10/12

    In a situation like this, where we are printing only constants, we could simply embed the blanks in the format

    string and not bother with format specifiers or additional arguments. The sequence of statements:

    printf (" month day\n");

    printf (" 1 10\n");

    printf (" 12 2\n");

    would produce exactly the same output. In most situations, however, the additional arguments will be variables.

    As such, we cannot necessarily determine what values they will hold when the program executes. In particular,when we have numeric variables, we will not be able to predict whether the value of the variable will be a one-

    digit number or a 4-digit number. Only by using field widths can we guarantee that the columns will line up

    correctly.

    Occasionally, when we write a program, we cannot even predict how large a field width we will need when a

    program executes. This implies that the field width itself needs to be a variable, for which the program will

    compute a value. Although it is rare for this situation to arise, it is worth mentioning how you can accomplish this.

    Just as was the case when we wanted to print the value of a variable, if we try to use a variable's name as a field

    width specifier, printfwill simply print the name to the screen. For example, assume that you have declared an

    integer variable named widthand have somehow computed a value for it. The call:

    printf ("%widthd\n", 10);

    will print:

    %widthd

    |

    To solve this problem, C uses an asterisk in the position of the field width specifier to indicate to printfthat it wilfind the variable that contains the value of the field width as an additional parameter. For instance, assume that

    the current value of widthis 5. The statement:

    printf ("%*d%*d\n", width, 10, width, 12);

    will print:

    10 12

    |

    Notice that the order of the additional parameters is exactly the same as the order of the specifiers in the format

    string, and that even though we use the same value (width) twice as a field width, it must appear twice in the

    parameter list.

    Precision specifiers

    Precision specifiers are most common with floating point numbers. We use them, as you might expect from the

    name, to indicate how many digits of precision we want to print. Compilers have a default precision for floating

  • 8/12/2019 Formatted Output and Printf

    11/12

    point numbers. The help facility or user's manual for your compiler will tell you what this default is, although you

    can also determine its value by simply printing a floating point number with a %f format specifier and counting

    how many digits there are after the decimal point. Quite often, we want to control this precision. A common

    example would be printing floating point numbers that represent monetary amounts. In this case, we will typically

    want just two digits after the decimal point. You can see from the syntax template that a period must precede the

    precision specifier. The period really is a syntactic device to help the compiler recognize a precision specifier

    when no field width exists, but the choice of a period serves to help remind the programmer that it represents the

    number of places after a decimal point in a floating point number. Just as for the field width specifier, theprogrammer may use a number or an asterisk as a precision specifier. The asterisk again indicates that the actual

    value of the precision specifier will be one of the additional parameters to the printfcall. For example,

    printf ("%.2f\n", 3.675);

    will print:

    3.68

    |

    Notice that printfrounds the number when a precision specifier requires that some digits must not appear.

    printf ("%.*f\n", width, 10.4);

    assuming that the current value of widthis 3, will print:

    10.400

    |

    Precision specifiers have no effect when used with the %c format specifier. They do have an effect when printing

    integers or strings, however. When you use a precision specifier with integer data, one of two things may happen

    If the precision specifier is smaller than the number of digits in the value, printf ignores the precision specifier.

    Thus,

    printf ("%.1d\n", 20);

    will print the entire number, "20". Here, the precision specifier is less than the number of digits in the value. On

    the other hand, if the precision specifier is larger than the number of digits in the value, printf will "pad" the

    number with leading zeros:

    printf ("%.4d\n", 20);

    will print "0020".

    With string data, the precision specifier actually dictates the maximumfield width. In other words, a

    programmer can use a precision specifier to force a string to occupy at mosta given number of columns. For

    instance,

    printf ("%.5s\n", "hello world");

    will print only "hello" (the first five characters). It is fairly rare to use precision specifiers in this fashion, but one

    situation in which it can be useful is when you need to print a table where one column is a string that may exceed

    the field width. In this case, you may wish to truncate the long string, rather than allow it to destroy the

    justification of the columns. Generally, when this happens, you will use both a field width specifier and a precision

  • 8/12/2019 Formatted Output and Printf

    12/12

    specifier, thus defining both the maximum and minimum number of columns that the string must occupy. Thus, if

    name is a variable that contains a string,

    printf ("%10.10s\n", name);

    will force printfto use exactly 10 columns to display the value of name. If the value is less than ten characters

    long, printfwill pad with leading blanks; if the value has more than ten characters, printf will print only the first

    ten.

    Flags

    Flags are fairly uncommon in format specifiers and although several flag options exist, you are most likely to use

    only two of them. The first is a minus sign, which you will use in conjunction with a field width specifier. By

    default, whenever printfmust pad output with blanks to make up a field width, the blanks precede the

    representation of the data. This results in right justification, as previously mentioned. In a few situations, you may

    wish to leftjustify data. That is, you may want values to line up along the left side, rather than the right side. In

    most cases, it will be best to right justify numbers and left justify strings. For instance, if you wanted to print a

    table of student names followed by their test scores, you would probably want the table to appear as follows:

    Mary Jones 89Sam Smith 100

    John Cook 78

    The names are lined up along the left, while the scores are lined up along the right. To print a single line of this

    table, your format string might look as follows:"%-15.15s%4d"

    The minus sign indicates left justification for the name, which must occupy exactly 15 columns. The %4d format

    specifier tells printf to right justify the score and to have it occupy four columns. Since we can assume that no

    score will actually be larger than a three digit number, specifying a field width of four ensures that we will have a

    blank space between the name and the score.

    The other flag that you may want to use is a plus sign. This flag is only meaningful with numeric data. By default,

    when printf displays a number, it prints a minus sign for negative numbers, but it does not print a plus sign for

    positive numbers. If you want the plus sign to appear, this flag will cause printfto display it. Thus,

    printf ("%+.3f", 2.5);

    will print "+2.500".