HP OpenVMS Systems

C Programming Language
Content starts here Compaq C

Compaq C
Run-Time Library Reference Manual for OpenVMS Systems

Previous Contents Index

Example 3-1 shows how the character-classification functions are used.

Example 3-1 Character-Classification Functions

/*       CHAP_3_CHARCLASS.C                                     */

/* This example uses the isalpha, isdigit, and isspace          */
/* functions to count the number of occurrences of letters,     */
/* digits, and white-space characters entered through the       */
/* standard input (stdin).                                      */

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

    char c;
    int i = 0,
        j = 0,
        k = 0;

    while ((c = getchar()) != EOF) {
        if (isalpha(c))
        if (isdigit(c))
        if (isspace(c))

    printf("Number of letters: %d\n", i);
    printf("Number of digits:  %d\n", j);
    printf("Number of spaces:  %d\n", k);

The sample input and output from Example 3-1 follows:

I saw 35 people riding bicycles on Main Street.[Return]
Number of letters: 36
Number of digits:  2
Number of spaces:  8

3.2 Character-Conversion Functions

The character-conversion functions convert one type of character to another type. These functions include:

ecvt         _tolower
fcvt         toupper
gcvt         _toupper
mbtowc       towctrans
mbrtowc      wctrans
mbsrtowcs    wcrtomb
toascii      wcsrtombs

For more information on each of these functions, see the Reference Section.

Example 3-2 shows how to use the ecvt function.

Example 3-2 Converting Double Values to an ASCII String

/*     CHAP_3_CHARCONV.C                                        */

/* This program uses the ecvt function to convert a double      */
/* value to a string. The program then prints the string.       */

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


    double val;         /* Value to be converted */

    int sign,           /* Variables for sign   */
        point;          /* and decimal place    */

    /*  Array for the converted string  */
    static char string[20];

    val = -3.1297830e-10;

    printf("original value: %e\n", val);
    if (sign)
        printf("value is negative\n");
        printf("value is positive\n");
    printf("decimal point at %d\n", point);

The output from Example 3-2 is as follows:

original value: -3.129783e-10
converted string: 31298
value is negative
decimal point at -9

Example 3-3 shows how to use the toupper and tolower functions.

Example 3-3 Changing Characters to and from Uppercase Letters

/*     CHAP_3_CONV_UPPERLOWER.C                                 */

/* This program uses the functions toupper and tolower to       */
/* convert uppercase to lowercase and lowercase to uppercase    */
/* using input from the standard input (stdin).                 */

#include <ctype.h>
#include <stdio.h>      /*  To use EOF identifier */
#include <stdlib.h>

    char c,

    while ((c = getchar()) != EOF) {
        if (c >= 'A' && c <= 'Z')
            ch = tolower(c);
            ch = toupper(c);

Sample input and output from Example 3-3 are as follows:

LET'S GO TO THE welcome INN.[Ctrl/Z]
let's go to the WELCOME inn.

3.3 String and Argument-List Functions

The Compaq C RTL contains a group of functions that manipulate strings. Some of these functions concatenate strings; others search a string for specific characters or perform some other comparison, such as determining the equality of two strings.

The Compaq C RTL also contains a set of functions that allow you to copy buffers containing binary data.

The set of functions defined and declared in the <varargs.h> and the <stdarg.h> header files provide a method of accessing variable-length argument lists. The <stdarg.h> functions are defined by the ANSI C Standard and are more portable than those defined in <varargs.h> .

The RTL functions such as printf and execl , for example, use variable-length argument lists. User-defined functions with variable-length argument lists that do not use <varargs.h> or <stdarg.h> are not portable due to the different argument-passing conventions of various machines.

The <stdarg.h> header file does not contain va_alist and va_dcl . The following shows a syntax example when using <stdarg.h> :

function_name(int arg1, ...)
va_list ap;
. . .

When using <varargs.h> :

  • The identifier va_alist is a parameter in the function definition.
  • va_dcl declares the parameter va_alist, a declaration that is not terminated with a semicolon (;);
  • The type va_list is used in the declaration of the variable used to traverse the list. You must declare at least one variable of type va_list when using <varargs.h> .

These names and declarations have the following syntax:

function_name(int arg1, ...)
va_list ap;

3.4 Program Examples

Example 3-4 shows how to use the strcat and strncat functions.

Example 3-4 Concatenating Two Strings

/*        CHAP_3_CONCAT.C                                      */

/*  This example uses strcat and strncat to concatenate two    */
/*  strings.                                                   */

#include <stdio.h>
#include <string.h>

    static char string1[80] = "Concatenates ";
    static char string2[] = "two strings ";
    static char string3[] = "up to a maximum of characters.";
    static char string4[] = "imum number of characters";

    printf("strcat:\t%s\n", strcat(string1, string2));
    printf("strncat ( 0):\t%s\n", strncat(string1, string3, 0));
    printf("strncat (11):\t%s\n", strncat(string1, string3, 11));
    printf("strncat (40):\t%s\n", strncat(string1, string4, 40));

Example 3-4 produces the following output:

strcat: Concatenates two strings
strncat ( 0): Concatenates two strings
strncat (11): Concatenates two strings up to a max
strncat (40): Concatenates two strings up to a maximum number of characters.

Example 3-5 shows how to use the strcspn function.

Example 3-5 Four Arguments to the strcspn Function

/*        CHAP_3_STRCSPN.C                                     */

/*  This example shows how strcspn interprets four             */
/*  different kinds of arguments.                              */

#include <stdio.h>


    printf("strcspn with null charset: %d\n",
            strcspn("abcdef", ""));

    printf("strcspn with null string: %d\n",
            strcspn("", "abcdef"));

    printf("strcspn(\"xabc\", \"abc\"): %d\n",
           strcspn("xabc", "abc"));

    printf("strcspn(\"abc\", \"def\"): %d\n",
            strcspn("abc", "def"));

The sample output, to the file strcspn.out, in Example 3-5 is as follows:


strcspn with null charset:  6
strcspn with null string:  0
strcspn("xabc","abc"):  1
strcspn("abc","def"):  3

Example 3-6 shows how to use the <stdarg.h> functions and definitions.

Example 3-6 Using the <stdarg.h > Functions and Definitions

/*        CHAP_3_STDARG.C                                       */

/* This routine accepts a variable number of string arguments,  */
/* preceded by a count of the number of such strings. It        */
/* allocates enough space in which to concatenate all of the    */
/* strings, concatenates them together, and returns the address */
/* of the new string. It returns NULL if there are no string    */
/* arguments, or if they are all null strings.                  */

#include <stdarg.h>     /* Include appropriate header files.    */
#include <stdlib.h>
#include <string.h>
#include <stdio.h>      /* For the "example" call in main       */

/* NSTRINGS is the maximum number of string arguments accepted  */
/* (arbitrary).                                                 */

#define NSTRINGS 10

char *concatenate(int n,...)
    va_list ap;         /* Declare the argument pointer. */

    char *list[NSTRINGS],
    int index = 0,
        size = 0;

    /* Check that the number of arguments is within range.   */

    if (n <= 0)
        return NULL;
    if (n > NSTRINGS)
        n = NSTRINGS;

    va_start(ap, n);    /* Initialize the argument pointer.  */

    do {
        /* Extract the next argument and save it. */

        list[index] = va_arg(ap, char *);

        size += strlen(list[index]);
    } while (++index < n);

    va_end(ap); /* Terminate use of ap. */

    if (size == 0)
        return NULL;

    string = malloc(size + 1);
    string[0] = '\0';

    /* Append each argument to the end of the growing result    */
    /*  string.                                                 */

    for (index = 0; index < n; ++index)
        strcat(string, list[index]);

    return string;

/* An example of calling this routine is */

main() {
    char *ret_string ;

    ret_string = concatenate(7, "This ", "message ", "is ",
                                "built with ", "a", " variable arg",
                                " list.") ;

    puts(ret_string) ;

The call to Example 3-6 produces the following output:

This message is built with a variable arg list.

Chapter 4
Error and Signal Handling

Table 4-1 lists and describes all the error- and signal-handling functions found in the Compaq C Run-Time Library (RTL). For more detailed information on each function, see the Reference Section.

Table 4-1 Error- and Signal-Handling Functions
Function Description
abort Raises the signal SIGABRT that terminates the execution of the program.
assert Puts diagnostics into programs.
atexit Registers a function to be called at program termination.
exit, _exit Terminates the current program.
perror Writes a short error message to stderr describing the current errno value.
strerror Maps the error code in errno to an error message string.
alarm Sends the signal SIGALARM to the invoking process after the number of seconds indicated by its argument has elapsed.
gsignal Generates a specified software signal.
kill Sends a SIGKILL signal to the process specified by a process ID.
longjmp Transfers control from a nested series of function invocations back to a predefined point without returning normally.
pause Causes the process to wait until it receives a signal.
raise Generates a specified signal.
setjmp Establishes the context for a later transfer of control from a nested series of function invocations, without returning normally.
sigaction Specifies the action to take upon delivery of a signal.
sigaddset Adds the specified individual signal.
sigblock Causes the signals in its argument to be added to the current set of signals being blocked from delivery.
sigdelset Deletes a specified individual signal.
sigemptyset Initializes the signal set to exclude all signals.
sigfillset Initializes the signal set to include all signals.
sigismember Tests whether a specified signal is a member of the signal set.
siglongjmp Nonlocal goto with signal handling.
sigmask Constructs the mask for a given signal number.
signal Catches or ignores a signal.
sigpause Blocks a specified set of signals and then waits for a signal that was not blocked.
sigpending Examines pending signals.
sigprocmask Sets the current signal mask.
sigsetjmp Sets jump point for a nonlocal goto.
sigsetmask Establishes the signals that are blocked from delivery.
sigstack Defines an alternate stack on which to process signals.
sigsuspend Atomically changes the set of blocked signals and waits for a signal.
sigvec Permanently assigns a handler for a specific signal.
ssignal Allows you to specify the action to be taken when a particular signal is raised.
VAXC$ESTABLISH Establishes an application exception handler in a way that is compatible with Compaq C RTL exception handling.

4.1 Error Handling

When an error occurs during a call to any of the Compaq C RTL functions, the function returns an unsuccessful status. Many RTL routines also set the external variable errno to a value that indicates the reason for the failure. You should always check the return value for an error situation.

The <errno.h> header file declares errno and symbolically defines the possible error codes. By including the <errno.h> header file in your program, you can check for specific error codes after a Compaq C RTL function call.

At program startup, the value of errno is 0. The value of errno can be set to a nonzero value by many Compaq C RTL functions. It is not reset to 0 by any Compaq C RTL function, so it is only valid to use errno after a Compaq C RTL function call has been made and a failure status returned. Table 4-2 lists the symbolic values that may be assigned to errno by the Compaq C RTL.

Table 4-2 The Error Code Symbolic Values
Symbolic Constant Description
E2BIG Argument list too long
EACCES Permission denied
EADDRINUSE Address already in use
EADDRNOTAVAIL Can't assign requested address
EAFNOSUPPORT Address family not supported
EAGAIN No more processes
EALIGN Alignment error
EALREADY Operation already in progress
EBADF Bad file number
EBADCAT Bad message catalogue format
EBADMSG Corrupted message detected
EBUSY Mount device busy
ECANCELED Operation canceled
ECHILD No children
ECONNABORTED Software caused connection abort
ECONNREFUSED Connection refused
ECONNRESET Connection reset by peer
EDEADLK Resource deadlock avoided
EDESTADDRREQ Destination address required
EDOM Math argument
EDQUOT Disk quota exceeded
EEXIST File exists
EFAIL Cannot start operation
EFAULT Bad address
EFBIG File too large
EFTYPE Inappropriate operation for file type
EHOSTDOWN Host is down
EHOSTUNREACH No route to host
EIDRM Identifier removed
EILSEQ Illegal byte sequence
EINPROGRESS Operation now in progress
EINPROG Asynchronous operation in progress
EINTR Interrupted system call
EINVAL Invalid argument
EIO I/O error
EISCONN Socket is already connected
EISDIR Is a directory
ELOOP Too many levels of symbolic links
EMFILE Too many open files
EMLINK Too many links
EMSGSIZE Message too long
ENAMETOOLONG File name too long
ENETDOWN Network is down
ENETRESET Network dropped connection on reset
ENETUNREACH Network is unreachable
ENFILE File table overflow
ENOBUFS No buffer space available
ENODEV No such device
ENOENT No such file or directory
ENOEXEC Exec format error
ENOLCK No locks available
ENOMEM Not enough core
ENOMSG No message of desired type
ENOPROTOOPT Protocol not available
ENOSPC No space left on device
ENOSYS Function not implemented
ENOTBLK Block device required
ENOTCONN Socket is not connected
ENOTDIR Not a directory
ENOTEMPTY Directory not empty
ENOTSOCK Socket operation on non-socket
ENOTSUP Function not implemented
ENOTTY Not a typewriter
ENWAIT No waiting processes
ENXIO No such device or address
EOPNOTSUPP Operation not supported on socket
EPERM Not owner
EPFNOSUPPORT Protocol family not supported
EPIPE Broken pipe
EPROCLIM Too many processes
EPROTONOSUPPORT Protocol not supported
EPROTOTYPE Protocol wrong type for socket
ERANGE Result too large
EREMOTE Too many levels of remote in path
EROFS Read-only file system
ESHUTDOWN Can't send after socket shutdown
ESOCKTNOSUPPORT Socket type not supported
ESPIPE Illegal seek
ESRCH No such process
ESTALE Stale NFS file handle
ETIMEDOUT Connection timed out
ETOOMANYREFS Too many references: can't splice
ETXTBSY Text file busy
EUSERS Too many users
EVMSERR OpenVMS-specific non-translatable error code
EWOULDBLOCK I/O operation would block channel
EXDEV Cross-device link

Previous Next Contents Index