United States

Compaq C

# Compaq C
Run-Time Library Reference Manual for OpenVMS Systems

Previous | Contents | Index

Table 2-5 decribes the conversion specifiers for formatted output.

Table 2-5 Conversion Specifiers for Formatted Output
Specifier | Output Type1 | Description
--- | --- | ---
d, i |  | Converts an `int` argument to signed decimal format.
o |  | Converts an `unsigned int` argument to unsigned octal format.
u |  | Converts an `unsigned int` argument to unsigned decimal format (giving a number in the range 0 to 4,294,967,295).
x, X |  | Converts an `unsigned int` argument to unsigned hexadecimal format (with or without a leading 0x). The letters `abcdef` are used for `x` conversion, and the letters `ABCDEF` are used for `X` conversion.
f |  | Converts a `float` or `double` argument to the format [--]mmm.nnnnnn. The number of n's is equal to the precision specification: If no precision is specified, the default is 6. If the precision is 0 and the # flag is specified, the decimal point appears but no n's appear. If the precision is 0 and the # flag is not specified, the decimal point also does not appear. If a decimal point appears, at least one digit appears before it. The value is rounded to the appropriate number of digits.
e, E |  | Converts a `float` or `double` argument to the format [--]m.nnnnnnE<pm symbol>xx. The number of n's is specified by the precision. If no precision is specified, the default is 6. If the precision is explicitly 0 and the # flag is specified, the decimal point appears but no n's appear. If the precision is explicitly 0 and the # flag is not specified, the decimal point also does not appear. An 'e' is printed for e conversion; an 'E' is printed for E conversion. The exponent always contains at least two digits. If the value is 0, the exponent is 0.
g, G |  | Converts a `float` or `double` argument to format f or e (or E if the G conversion specifier is used), with the precision specifying the number of significant digits. If the precision is 0, it is taken as 1. The format used depends on the value of the argument: format e (or E) is used only if the exponent resulting from such a conversion is less than --4, or is greater than or equal to the precision; otherwise, format f is used. Trailing zeros are suppressed in the fractional portion of the result. A decimal point appears only if it is followed by a digit.
c | Byte | Converts an `int` argument to an `unsigned char` , and writes the resulting byte. If the optional character l (lowercase ell) precedes this conversion specifier, then the specifier converts a `wchar_t` argument to an array of bytes representing the character, and writes the resulting character. If the field width is specified and the resulting character occupies fewer bytes than the field width, it will be padded to the given width with space characters. If the precision is specified, the behavior is undefined.
| Wide-character | If an l (lowercase ell) does not precede the c specifier, then the `int` argument is converted to a wide character as if by calling `btowc` , and the resulting character is written. If an l (lowercase ell) precedes the c specifier, then the specifier converts a `wchar_t` argument to an array of bytes representing the character, and writes the resulting character. If the field width is specified and the resulting character occupies fewer characters than the field width, it will be padded to the given width with space characters. If the precision is specified, the behavior is undefined.
C | Byte | Converts a `wchar_t` argument to an array of bytes representing the character, and writes the resulting character. If the field width is specified and the resulting character occupies fewer bytes than the field width, it will be padded to the given width with space characters. If the precision is specified, the behavior is undefined.
| Wide-character | Converts a `wchar_t` argument to an array of bytes representing the character, and writes the resulting character. If the field width is specified and the resulting character occupies fewer wide characters than the field width, it will be padded to the given width with space characters. If the precision is specified, the behavior is undefined.
s | Byte | Requires an argument that is a pointer to an array of characters of type `char` . The argument is used to write characters until a null character is encountered or until the number of characters indicated by the precision specification is exhausted. If the precision specification is 0 or omitted, all characters up to a null are output. If the optional character l (lowercase ell) precedes this conversion specifier, then the specifier converts an array of wide-character codes to multibyte characters, and writes the multibyte characters. Requires an argument that is a pointer to an array of wide characters of type `wchar_t` . Characters are written until a null wide character is encountered or until the number of bytes indicated by the precision specification is exhausted. If the precision specification is omitted or is greater than the size of the array of converted bytes, the array of wide characters must be terminated by a null wide character.
| Wide-character | If an l (lowercase ell) does not precede the s specifier, then the specifier converts an array of multibyte characters, as if by calling `mbrtowc` for each multibyte character, and writes the resulting characters until a null wide character is encountered or the number of wide characters indicated by the precision specification is exhausted. If the precision specification is omitted or is greater than the size of the array of converted characters, the converted array must be terminated by a null wide character. If an l precedes this conversion specifier, then the argument is a pointer to an array of `wchar_t` . Characters from this array are written until a null wide character is encountered or the number of wide characters indicated by the precision specification is exhausted. If the precision specification is omitted or is greater than the size of the array, the array must be terminated by a null wide character.
S | Byte | Converts an array of wide-character codes to multibyte characters, and writes the multibyte characters. Requires an argument that is a pointer to an array of wide characters of type `wchar_t` . Characters are written until a null wide character is encountered or until the number of bytes indicated by the precision specification is exhausted. If the precision specification is omitted or is greater than the size of the array of converted bytes, the array of wide characters must be terminated by a null wide character.
| Wide-character | The argument is a pointer to an array of `wchar_t` . Characters from this array are written until a null wide character is encountered or the number of wide characters indicated by the precision specification is exhausted. If the precision specification is omitted or is greater than the size of the array, the array must be terminated by a null wide character.
p |  | Requires an argument that is a pointer to `void` . The value of the pointer is output as a hexadecimal number.
n |  | Requires an argument that is a pointer to an integer. The integer is assigned the number of characters written to the output stream so far by this call to the formatted output function. No argument is converted.
% |  | Writes out the percent symbol. No conversion is performed. The complete conversion specification would be %%.

1Either Byte or Wide-character. Where neither is shown for a given specifier, the specifier description applies to both.

# 2.5 Terminal I/O

Compaq C defines three file pointers that allow you to perform I/O to and from the logical devices usually associated with your terminal (for interactive jobs) or a batch stream (for batch jobs). In the OpenVMS environment, the three permanent process files SYS$INPUT, SYS$OUTPUT, and SYS$ERROR perform the same functions for both interactive and batch jobs. Terminal I/O refers to both terminal and batch stream I/O. The file pointers stdin, stdout, and stderr are defined when you include the `<stdio.h>` header file using the `#include` preprocessor directive.

The stdin file pointer is associated with the terminal to perform input. This file is equivalent to SYS$INPUT. The stdout file pointer is associated with the terminal to perform output. This file is equivalent to SYS$OUTPUT. The stderr file pointer is associated with the terminal to report run-time errors. This file is equivalent to SYS$ERROR.

There are three file descriptors that refer to the terminal. The file descriptor 0 is equivalent to SYS$INPUT, 1 is equivalent to SYS$OUTPUT, and 2 is equivalent to SYS$ERROR.

When performing I/O at the terminal, you can use Standard I/O functions and macros (specifying the pointers stdin, stdout, or stderr as arguments), you can use UNIX I/O functions (giving the corresponding file descriptor as an argument), or you can use the Terminal I/O functions and macros. There is no functional advantage to using one type of I/O over another; the Terminal I/O functions might save keystrokes since there are no arguments.

# 2.6 Program Examples

This section gives some program examples that show how the I/O functions can be used in applications.

Example 2-1 shows the `printf` function.

Example 2-1 Output of the Conversion Specifications

    /*      CHAP_2_OUT_CONV.C                               */

    /* This program uses the printf function to print the   */
    /* various conversion specifications and their affect   */
    /* on the output.                                       */

    /* Include the proper header files in case printf has   */
    /* to return EOF.                                       */

    #include <stdlib.h>
    #include <stdio.h>
    #include <wchar.h>

    #define WIDE_STR_SIZE 20

    main()
    {
        double val = 123345.5;
        char c = 'C';
        int i = -1500000000;
        char *s = "thomasina";
        wchar_t wc;
        wchar_t ws[WIDE_STR_SIZE];

        /* Produce a wide character and a wide character string */

        if (mbtowc(&wc, "W", 1) == -1) {
            perror("mbtowc");
            exit(EXIT_FAILURE);
        }

        if (mbstowcs(ws, "THOMASINA", WIDE_STR_SIZE) == -1) {
            perror("mbstowcs");
            exit(EXIT_FAILURE);
        }

        /* Print the specification code, a colon, two tabs, and the  */
        /* formatted output value delimited by the angle bracket     */
        /* characters (<>).                                          */

        printf("%%9.4f:\t\t<%9.4f>\n", val);
        printf("%%9f:\t\t<%9f>\n", val);
        printf("%%9.0f:\t\t<%9.0f>\n", val);
        printf("%%-9.0f:\t\t<%-9.0f>\n\n", val);

        printf("%%11.6e:\t\t<%11.6e>\n", val);
        printf("%%11e:\t\t<%11e>\n", val);
        printf("%%11.0e:\t\t<%11.0e>\n", val);
        printf("%%-11.0e:\t\t<%-11.0e>\n\n", val);

        printf("%%11g:\t\t<%11g>\n", val);
        printf("%%9g:\t\t<%9g>\n\n", val);

        printf("%%d:\t\t<%d>\n", c);
        printf("%%c:\t\t<%c>\n", c);
        printf("%%o:\t\t<%o>\n", c);
        printf("%%x:\t\t<%x>\n\n", c);

        printf("%%d:\t\t<%d>\n", i);
        printf("%%u:\t\t<%u>\n", i);
        printf("%%x:\t\t<%x>\n\n", i);

        printf("%%s:\t\t<%s>\n", s);
        printf("%%-9.6s:\t\t<%-9.6s>\n", s);
        printf("%%-*.*s:\t\t<%-*.*s>\n", 9, 5, s);
        printf("%%6.0s:\t\t<%6.0s>\n\n", s);
        printf("%%C:\t\t<%C>\n", wc);
        printf("%%S:\t\t<%S>\n", ws);
        printf("%%-9.6S:\t\t<%-9.6S>\n", ws);
        printf("%%-*.*S:\t\t<%-*.*S>\n", 9, 5, ws);
        printf("%%6.0S:\t\t<%6.0S>\n\n", ws);
    }

Running Example 2-1 produces the following output:

    $ RUN  EXAMPLE
    %9.4f:          <123345.5000>
    %9f:            <123345.500000>
    %9.0f:          <   123346>
    %-9.0f:         <123346   >
    %11.6e:         <1.233455e+05>
    %11e:           <1.233455e+05>
    %11.0e:         <      1e+05>
    %-11.0e:        <1e+05      >
    %11g:           <     123346>
    %9g:            <   123346>
    %d:             <67>
    %c:             <C>
    %o:             <103>
    %x:             <43>
    %d:             <-1500000000>
    %u:             <2794967296>
    %x:             <a697d100>
    %s:             <thomasina>
    %-9.6s:         <thomas   >
    %-*.*s:         <thoma    >
    %6.0s:          <      >
    %C:             <W>
    %S:             <THOMASINA>
    %-9.6S:         <THOMAS   >
    %-*.*S:         <THOMA    >
    %6.0S:          <      >
    $

Example 2-2 shows the use of the `fopen` , `ftell` , `sprintf` , `fputs` , `fseek` , `fgets` , and `fclose` functions.

Example 2-2 Using the Standard I/O Functions

    /*      CHAP_2_STDIO.C  */

    /* This program establishes a file pointer, writes lines from   */
    /* a buffer to the file, moves the file pointer to the second   */
    /* record, copies the record to the buffer, and then prints     */
    /* the buffer to the screen.                                    */

    #include <stdio.h>
    #include <stdlib.h>

    main()
    {
        char buffer[32];
        int i,
            pos;
        FILE *fptr;

        /*  Set file pointer.            */
        fptr = fopen("data.dat", "w+");
        if (fptr == NULL) {
            perror("fopen");
            exit(EXIT_FAILURE);
        }

        for (i = 1; i < 5; i++) {
            if (i == 2)     /*  Get position of record 2. */
                pos = ftell(fptr);
            /*  Print a line to the buffer.  */
            sprintf(buffer, "test data line %d\n", i);
            /*  Print buffer to the record.  */
            fputs(buffer, fptr);
        }

        /*  Go to record number 2.       */
        if (fseek(fptr, pos, 0) < 0) {
            perror("fseek");        /*  Exit on fseek error. */
            exit(EXIT_FAILURE);
        }

        /*  Read record 2 in the buffer. */
        if (fgets(buffer, 32, fptr) == NULL) {
            perror("fgets");        /*  Exit on fgets error.  */
            exit(EXIT_FAILURE);
        }
        /*  Print the buffer.       */
        printf("Data in record 2 is: %s", buffer);
        fclose(fptr);       /*  Close the file.     */
    }

Running Example 2-2 produces the following result:

    $ RUN  EXAMPLE
    Data in record 2 is: test data line 2

The output to DATA.DAT from Example 2-2 is:

    test data line 1
    test data line 2
    test data line 3
    test data line 4

Example 2-3 Using Wide Character I/O Functions

    /*      CHAP_2_WC_IO.C                                          */

    /* This program establishes a file pointer, writes lines from   */
    /* a buffer to the file using wide-character codes, moves the   */
    /* file pointer to the second record, copies the record to the  */
    /* wide-character buffer, and then prints the buffer to the     */
    /* screen.                                                      */

    #include <stdio.h>
    #include <stdlib.h>
    #include <wchar.h>

    main()
    {
        char flat_buffer[32];
        wchar_t wide_buffer[32];
        wchar_t format[32];
        int i,
            pos;
        FILE *fptr;

        /*  Set file pointer.            */
        fptr = fopen("data.dat", "w+");
        if (fptr == NULL) {
            perror("fopen");
            exit(EXIT_FAILURE);
        }

        for (i = 1; i < 5; i++) {
            if (i == 2)     /*  Get position of record 2. */
                pos = ftell(fptr);
            /*  Print a line to the buffer.  */
            sprintf(flat_buffer, "test data line %d\n", i);
            if (mbstowcs(wide_buffer, flat_buffer, 32) == -1) {
                perror("mbstowcs");
                exit(EXIT_FAILURE);
            }

            /*  Print buffer to the record.  */
            fputws(wide_buffer, fptr);
        }

        /*  Go to record number 2. */
        if (fseek(fptr, pos, 0) < 0) {
            perror("fseek");        /*  Exit on fseek error. */
            exit(EXIT_FAILURE);
        }

        /*  Put record 2 in the buffer.  */
        if (fgetws(wide_buffer, 32, fptr) == NULL) {
            perror("fgetws");       /*  Exit on fgets error. */
            exit(EXIT_FAILURE);
        }
        /*  Print the buffer. */
        printf("Data in record 2 is: %S", wide_buffer);
        fclose(fptr);               /*  Close the file.  */
    }

Running Example 2-3 produces the following result:

    $ RUN  EXAMPLE
    Data in record 2 is: test data line 2

The output to DATA.DAT from Example 2-3 is:

    test data line 1
    test data line 2
    test data line 3
    test data line 4

Example 2-4 shows the use of both a file pointer and a file descriptor to access a single file.

Example 2-4 I/O Using File Descriptors and Pointers

    /*      CHAP_2_FILE_DIS_AND_POINTER.C                           */

    /* The following example creates a file with variable-length    */
    /* records (rfm=var) and the carriage-return attribute (rat=cr).*/
    /*                                                              */
    /* The program uses creat to create and open the file, and      */
    /* fdopen to associate the file descriptor with a file pointer. */
    /* After using the fdopen function, the file must be referenced */
    /* using the Standard I/O functions.                            */

    #include <unixio.h>
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #define ERROR 0
    #define ERROR1 -1
    #define BUFFSIZE 132

    main()
    {
        char buffer[BUFFSIZE];
        int fildes;
        FILE *fp;

        if ((fildes = creat("data.dat", 0, "rat=cr",
                            "rfm=var")) == ERROR1) {
            perror("DATA.DAT: creat() failed\n");
            exit(EXIT_FAILURE);
        }

        if ((fp = fdopen(fildes, "w")) == NULL) {
            perror("DATA.DAT: fdopen() failed\n");
            exit(EXIT_FAILURE);
        }
        while (fgets(buffer, BUFFSIZE, stdin) != NULL)
            if (fwrite(buffer, strlen(buffer), 1, fp) == ERROR) {
                perror("DATA.DAT: fwrite() failed\n");
                exit(EXIT_FAILURE);
            }

        if (fclose(fp) == EOF) {
            perror("DATA.DAT: fclose() failed\n");
            exit(EXIT_FAILURE);
        }
    }

Previous | Next | Contents | Index

privacy and legal statement