Professional Documents
Culture Documents
Oups - Essential.guide - to.ANSI.C.1988.SCAN DARKCROWN
Oups - Essential.guide - to.ANSI.C.1988.SCAN DARKCROWN
-ANSIC
Essential Guide to
HOWARD W. SAMS & COMPANY
HAYDEN BOOKS
Related Titles
The Waite Group’s The Waite Group’s
C Primer Plus, QuickC™ Bible
Revised Edition Naba Barkakati
Mitchell Waite, Stephen Prata,
and. Donald Martin The Waite Group’s
Turbo C® Bible
The Waite Group’s Naba Barkakati
Advanced C Primer + +
Stephen Prata
The Waite Group’s
Turbo C® Programming
The Waite Group’s
for the PC,
C++ Programming
Revised Edition
(Version 2.0)
Robert Lafore
Edited by The Waite Group
ANSI C
NEVI ort Barkakati
FIRST EDITION
SECOND PRINTING—1989 2
All rights reserved. No part of this book shall be reproduced, stored in a retrieval
system, Or transmitted by any means, electronic, mechanical, photocopying,
recording, or otherwise, without written permission from the publisher, No
patent liability is assumed with respect to the use of the information contained
herein. While every precaution has been taken in the preparation of this book,
the publisher and author assume no responsibility for errors or omissions.
Neither is any liability assumed for damages resulting from the use of the
information contained herein.
Trademarks
All terms mentioned in this book that are known to be trademarks or service
marks are listed below. In addition, terms suspected of being trademarks or
service marks have been appropriately capitalized. Howard W. Sams & Company
cannot attest to the accuracy of this information. Use of a term in this book
should not be regarded as affecting the validity of any trademark or service
mark.
IBM, IBM PC, and IBM AT are registered trademarks of the International Business
Machines Corporation,
Intel and Intel 8088 and 8086 are registered trademarks of Intel Corporation.
Macintosh is a registered trademark of Macintosh Laboratory, Inc., licensed by
Apple Computers, Inc,
Microsoft, MS-DOS, and QuickC are registered trademarks of Microsoft
Corporation,
MC68000 is a registered trademark of Motorola, Inc.
Turbo C is a registered trademark of Borland International.
UNIX is a registered trademark of AT&T Bell Laboratories,
VAX is a registered trademark of Digital Equipment Corporation.
Contents
Preface ix
Acknowledgments ><
An Overview of ANSI C
1. How to Use This Essential Guide
Organization
What You Need to Know to Use This Guide
Typographic Conventions
An Overview of ANSI C
Introduction
Structure of a C Program NIN
Trigraphs, Multiple Characters,
and Escape Sequences
What ANSI C Means to You
Data Types in C
New Data Type: enum
Arrays
Pointers
Structures and Unions
Naming Your Own Data Types
Visibility and Lifetime of Variables
New Keywords: const and volatile
Function Declarations
Prototypes
The Type void
Expressions in C
Statements in C
Function Definitions
Complex Return Types for Functions
Pointers to Functions
ANSI C Keywords
Index 225
Preface
features
Acknowledgments
The guidance of Mitchell Waite and the thoughtful comments of
Harry Henderson have made writing this book a pleasant learn-
ing experience. Thanks to Scott Calamar for making sure I had
the support needed to complete the book on time. Finally, Iam
thankful for the love and support of my wife Leha and my
daughters Ivy and Emily as I worked on yet another book.
Nabajyoti Barkakati
The Waite Group wishes to thank the following people for their
contributions. First, thanks to Naba Barkakati. Naba’s careful cal-
culations made this book the most comprehensive ANSI pocket
guide on the market. Thanks to Harry Henderson for his content
review and careful guidance. Thanks to Jim Rounds for his devel-
opment management, and to Wendy Ford, Marj Colvin, and Don
MacLaren for their management of production and careful edit-
ing. Thanks to Glenn Santner for his pursuit of artistic integrity.
Finally, thanks to Richard Swadley, Jim Hill, and Jim Irizarry of
Howard Sams for making this series possible.
Mitchell Waite
||
An Overview of ANSI C
How to Use This
Essential Guide
Organization
The Waite Group's Essential Guide to ANSI Cis a handy, concise,
and practical guide to the essential aspects of the ANSI C lan-
guage and the library routines. It is organized in four parts. Part I
is an overview of ANSI C and the C preprocessor. In addition to
summarizing the ANSI C library and its keywords, the Guide in-
troduces the new keywords that differentiate ANSI C from the
K&R C, such as volatile and const; new types, such as enum and
void; and the new token-pasting and string-izing operators of
the preprocessor.
Parts II, III], and IV cover the ANSI C library in detail. Each
group of library functions starts with a short tutorial section fol-
lowed by alphabetically arranged reference entries on the
group’s functions. The reference entries are generally presented
in the form shown in Figure 1-1, although not all are used in ex-
ample programs.
Part II describes the file input/output (I/O) routines in the ANSI
C library, in particular, the “stream” model of files in C and how I/O
is performed with the streams. Part III introduces the dynamic
memory allocation facilities in C and explains how to handle ab-
normal conditions occurring during the execution of your pro-
gram. This part presents such routines as malloc and free and
explains how advanced process control routines such as setjmp
and longjmp work. Finally, Part 1V discusses data processing with
the C library, including how to compute math formulas, manipu-
late strings, search and sort, and get the current time and date.
3
4 An Overview of ANSI C
: fclose <
Full ANSI prototype:
Describes argument ee
: includes u
deciataiia) se ies Use fclose to close the stream specified by stream. If the stream
files needed “ was open for writing, the content of the buffer associated with the
stream is written to the file (‘flushed’) before the file is closed. If it
was open for reading, unread data in the buffer are discarded.
: oS Syntax
A sample invocation Of —ginctude <stdio.m
the function in a real int fclose(FILE *stream);
fe bse *stream; Pointer to stream to be closed
application
Example Call
fclose(infile);
Returns
Describes the return ae the stream was successfully closed, feof returns a zero; other-
value, if any wise, it returns EOF.
See Also
ae fflush
Quick C Bible" are ideal for this purpose. These books comple-
ment this essential guide by providing specific compiler details,
references to graphics and other compiler-specific functions, ex-
tensive tutorials, and complete example programs.
1. Brian W. Kernighan and Dennis M. Ritchie, The C Program-
ming Language, Second Edition, Prentice-Hall, Inc., Engle-
wood-Cliffs, NJ, 1988, 261 pages.
2. Brian W. Kernighan and Dennis M. Ritchie, The C Program-
ming Language, First Edition, Prentice-Hall, Inc., Engle-
wood-Cliffs, NJ, 1978, 228 pages.
3. Stephen G. Kochan, Programming in C, Revised Edition,
Hayden Books, a Division of Howard W. Sams & Company,
Indianapolis, IN, 1988, 476 pages.
4. Stephen G. Kochan, Programming in ANSI C, Hayden
Books, a Division of Howard W. Sams & Company, Indian-
apolis, IN, 1988, 450 pages.
5. Robert Lafore, The Waite Group’s Microsoft C Program-
ming for the IBM, Howard W. Sams & Company, Indianapo-
lis, IN, 1987, 681 pages.
6. Robert Lafore, The Waite Group’s Turbo C Programming
for the IBM, Howard W. Sams & Company, Indianapolis, IN,
1987, 681 pages.
- 7. Mitchell Waite, Stephen Prata, and Donald Martin, The
Waite Group's C Primer Plus, Revised Edition, Howard W.
Sams & Company, Indianapolis, IN, 1987, 536 pages.
8. Stephen Prata, The Waite Group’s Advanced C Primer++,
Howard W. Sams & Company, Indianapolis, IN, 1986, 502
pages.
9. Nabajyoti Barkakati, The Waite Group's Microsoft C Bible,
Howard W. Sams & Company, Indianapolis, IN, 1988, 808
pages.
10. Nabajyoti Barkakati, The Waite Group's Turbo C Bible,
Howard W. Sams & Company, Indianapolis, IN, 1988, 900
pages.
11. Nabajyoti Barkakati, The Waite Group’s QuickC Bible,
Howard W. Sams & Company, Indianapolis, IN, 1988, 800
pages.
Typographic Conventions
The Waite Group’s Essential Guide to ANSI C uses a simple nota-
tional style. All function names, keywords, and variable names ap-
pearing in text are typeset in ¢talics. Annotation of program code
under the Syntax headings in the reference pages is also italicized.
File names and constants are in uppercase roman. All program list-
ings are typeset in a monospace font for easy reading.
Every effort has been made to reproduce single computer
lines in their entirety. The practical limits of typeset line length,
however, cause an occasional line break. Where this occurs, the
broken portion is placed at the right margin of the second line as
a visual signal.
: Eyer pea
7 8 AES oh catek
a S
» a cal
7 Mts
ae {2fe
an
ARS ES
e Ee Niee y
bah
leetat
& baile
Tae ; \\ eg : ae Hs ,
ie wel . , ae ea gem YS ‘
5 aeurte., 8 ba liad
-_ is u
. - ‘> pa ry
et Te
: d ss ”
~S ' " itvrsAs rd “ * iy.
~ “ ed vi “ey > vit
WARGAMES
| aT Raabith ato
Salve) bee rah ag et PHS tt
Oe ae 111th a eS at ng
} an > wy oo cH ah Rkerg NaS) Y “aie
\ WS ered ? dati yi bs tie =
Bf
COMPUTER TITLES:
Hardware Programming Languages
O Applei4o =) Macintosh 101 JC 103 OD Pascal Los
OC Commodore tio O Prolog u12 C Assembly to1
COIBM & Compatibles 114 0 BASIC to2 O HyperTalk tia
Business Applications Troubleshooting & Repair
DC Word Processing so1 CZ Computers s05
O Data Base Jo4 C Peripherals sto
C Spreadsheets Jo2
Operating Systems Other
0 MS-DOS kos 0S/2 ki0 CO Communications/Networking mos
0 CP/M koi OCOUNIX ko3 CO AI/Expert Systems tis
ELECTRONICS TITLES:
Amateur Radio 101 OC Instrumentation 105
© Audio 103 : Digital Electronics T11
O Basic Electronics 120 Troubleshooting & Repair
Basic Electricity 121 © Audiosi ~~ O Television sos
Electronics Design 112 2 VCR soi Compact Disc so2
CO Electronics Projects tos CZ Automotive sos
D Satellites tos C) Microwave Oven so3
Name
Title
Company
Address
City
State/Zip
Daytime Telephone No.
Introduction
The composition of C—a sparse core with a large support li-
brary—makes it an ideal language for developing software. The
core offers a good selection of data types and control structures
while all additional tasks, including I/O, math computations,
and access to peripheral devices are relegated to a library of func-
tions. This access to all parts of the system enables you to har-
ness the system’s full potential.
The forthcoming ANSI standardization makes C even more
appealing because the draft proposal, now in its final stages of
review, greatly enhances the portability of C programs by defin-
ing all aspects of the language: from the preprocessor to the stan-
dard C library.
This book is designed to help you use ANSI C to its fullest
potential. The focus is on the keywords of the language, the pre-
processor directives, and the library routines. The concepts that
unify each group of related functions are presented in a tutorial
section followed by individual reference entries on each mem-
ber function.
The next four chapters constitute a refresher course on C.
Chapters 3, 4, and 5 describe the ANSI C preprocessor, the ANSI
C language, and the ANSI C library, respectively. The following
discussion of the basic features of C points out how the pro-
posed ANSI standard affects a particular feature. For your con-
venience these notes are marked in the text with this symbol:
Structure of a C Program
As shown in Figure 2-1, a file containing a C program consists of
preprocessor directives, declarations of variables and functions,
i
8 An Overview of ANSI C
a main function, the body of the main function, and other func-
tions. The body of each function, including main, contains ex-
pressions and statements.
# include <stdio.h>
Preprocessor # include <math.h>
directives # definePI3.14159
Variable and # define SQUARE (x) ((x) * (x))
ae #
22
22/
22)
29" SSS
22
22!
22) Sey
SS
2 y
Preprocessor Directives
The preprocessor processes the source text of aprogram file and
acts on commands, called “preprocessor directives,’ embedded
in the text. These directives begin with the character #. Usually
the compiler automatically invokes the preprocessor before be-
ginning compilation, but most compilers allow you to invoke
the preprocessor alone by using compiler options. The prepro-
cessor provides three important services that enable users to
make their programs modular, more easily readable, and easier
to customize for different computer systems: including the con-
tents of a file into a C program (file inclusion), replacing one
string with another (token replacement and macro processing),
and compiling selected portions of aprogram (conditional com-
pilation).
File Inclusion
The ability to include files provides for modularity. Declarations
that are used repeatedly can be kept in a file and included where
needed using #include, which can be used in two forms:
#include <stdio.h>
#include "local.h"
The first and the most common format asks the preprocessor to
read in a named file, in this case a standard C header file, stdio.h,
from the default location for the include files in the system. The
second form of the directive typically asks the preprocessor to
look for local.h in the directory in which the source code resides
(this varies from one compiler to another).
11
12 An Overview of ANSI C
#define MSC5 5
#define version(x) MSC#H#Hx
value_now(counter) ;
Conditional Compilation
This feature lets you control which parts of asource file get com-
piled, under which conditions. This capability enables you to
maintain a single set of source files that can be selectively com-
piled with different compilers and in different environments.
Other forms of customization are also possible; for example.
you may decide to insert for debugging prizf statements that
are compiled only if a symbol named DEBUG is defined,
The directives #if, #elif, #else, and #endif are the primary
means of conditionally excluding portions of text from being
used by the compiler. The #ifdef and #ifidef directives, special
cases of the #/f directive, are used more widely than the other
conditional directives. The typical use of these directives is of
the form:
#ifdef DEBUG
printf("Count = %d\n'"', count);
#endif
#if VERSION == 1
#include <version1.h>
#elif VERSION ==
#include <version2.h>
Hendi f
14° An Overview of ANSI C
__DATE__ The date of translation of the source file in the form of a string:
“MMM DD YYYY” (such as “Jul 12 1988”)
sya || a A string containing the name of the source file
See INESes The line number of the current source file as a decimal constant
__STDC__ __ The decimal constant 1, indicating that the C compiler conforms to
the ANSI standard
__TIME__ The time of translation of the source file as a string of the form:
“HH:MM:SS”
ne
¥ ) sty
iq. wdttasa
Mlne memes
te Va sTGOF; ve
or { had “ey . ¥ ore +
WZ)
‘
ageer i Pz .
<a ‘ ' ¢.20
a
;
=
' >
( thy
“Ee re ie Aer
wae dhe
~ — ee a a
—=
a, yee
>
ws
~ >
- Piel
~
a)
=
~r _
The ANSI C Language
Declarations in C
All variables and functions must be declared before they are
used. The declaration ofa variable specifies the “visibility” and
the “lifetime” of the variable, its “type;’ and, where allowed, its
initial value. The declaration of a function specifies its visibility
as well as the type of value it returns.
Data Types in C
There are four basic data types in C: char and int are for storing
characters and integers, and float and double are for floating-
point numbers. The storage sizes for the floating-point types
depend on the convention used to represent floating-point
numbers in binary form. ANSI C uses the Institute of Electrical
and Electronics Engineers (IEEE) format for floating-point num-
bers. A char takes a single byte while an int is the same size as a
word on the underlying machine (for instance, 2 bytes on the
IBM PC and 4 bytes on a DEC VAX). Here are some declarations
using the basic types:
chain 9716;
int COUNEMP IEA is
filtoate a0;
double x, y, 2;
The basic data types can be expanded into a much larger set
with the use of Jong, short, and unsigned qualifiers as prefixes.
The Jong and the short qualifiers are size modifiers. For example,
a long int is 4 bytes long in ANSI C and capable of holding a
much larger value than a short, which is only 2 bytes. The size of
an int is system dependent but it is guaranteed to be at least as
large as a short. The unsigned qualifier is for int and char types
only. Normally, each of these types holds negative as well as pos-
17
18 An Overview of ANSI C
Note that when the Jong, short, and unsigned qualifiers are used
with int types, you can drop the int from the declaration. Also,
among the floating-point types, only double takes the Jong qual-
ifier.
The exact sizes of various data types and the maximum val-
ues they can hold depend on the compiler. ANSI C specifies that
these limits be defined in two header files: /imits.b and float.h.
The constants that are defined in these files are summarized later
in this chapter.
The example shows several properties of enw. The first line de-
fines boolean to be an enumerated type. The list within the
braces shows the constant names that are valid values of an
enum boolean variable. Each constant can be initialized to a
value of your choice and there can be several constants that use
the same value. In this example, the constants false, no, and off
are 0 and true, yes, and on are 1. The second line shows the dec-
laration of an enumerated variable of type boolean. Its name is
flag and it is initially set to the constant off. Note that enum does
not introduce a new basic data type; it simply improves the read-
ability of your programs.
The /ong double is another type of floating-point variable
specified in the ANSI standard. Some older compilers recog-
nized the type /ong float, which is no longer valid under the pro-
posed standard.
Arrays
An “array” is a convenient way to organize a large number of
identical data items. You can declare arrays of any type of data
4—The ANSI C Language 19
Pointers
A “pointer” is a variable that can hold the address of an object
that can be either a variable or a function. If px is a pointer to an
integer you would declare and use it as
int *px, Xx;
px = &x;
pxl99]
which is equivalent to
* (pxt+99)
int current_object_id;
.
.
main()
{
int id;
d = create_objectQ;
—+
oe
eo
1;
int create_object()
£
int id;
if(current_object_id == 0) ...
return(id);
2d
The variable current_object_id is declared before any of the
functions (including main), so it is visible in the entire source
file. On the other hand, the variable 7d is local to main( )and to
create__object().Each function has its own copy of id. Changes
made to one copy do not affect any of the others. The variable
current_object__id is not only visible in its source file, it can
even be referenced from other files with the declaration
extern int current_object_id;
This is how global variables are used in C. Since the variable may
be accessed at any time during the execution of the program,
these variables are allocated storage for the life of the program
and are said to have global “lifetimes.”
The qualifier, static, also declares variables with global life-
times, but it restricts the visibility of variables to a single source
file. For example, you could define the variable current_ object
—id as
static int current_object_id = 0;
in a file and use it within the file without altering its globally vis-
ible counterpart with the same name. In other words, you have a
separate storage location for the copy of current_object_id
that is visible only in the file where it is declared.
When a variable (¢d in our example) is defined within the
4—The ANSI C Language 23
Before all functions ina None Entire file plus other Until program ends
file (may be initialized files where variable (Global)
here) is declared extern
Before all functions ina —_extern Entire file plus other Global
file (cannot be initialized files where variable
here) is declared extern
including file where
originally declared
Before all functions ina __ static Only in that file Global
file
Inside a function None Only in that function Until function
or auto returns
Inside a function register Only in that function Until function
returns
Inside a function static Only in that function Global
the compiler need not generate code to load the value ofx from
24 An Overview of ANSI C
Function Declarations
A function declaration tells the compiler the type of value the
function returns and the number and type of arguments it takes.
Most programmers are used to declaring functions only when
they return something other than an int. For example, a typical
declaration would be
char *locate_charQ;
Prototypes
The introduction of “function prototypes” is probably the most
significant feature of ANSI C. It requires you to declare the for-
mal parameters that a function takes as well as the return value. If
our sample function /ocate__char() takes a string and an integer
as an argument, the ANSI-style prototype for this function is
char *locate_char(char *, int);
with the formal argument list shown with the type of each pa-
rameter only. You may include an identifier for each formal pa-
rameter, such as
char *locate_char(char *str, int c);
In this case, the prototype can look exactly like the first line in
the definition of the function, except that in the prototype you
terminate the line with a semicolon.
Prototypes help the compiler check function arguments
and generate code that uses a faster mechanism for passing argu-
ments. Since the prototype tells the compiler the exact number
and type of arguments to expect, it can catch any mistakes you
might make when calling a function, such as passing the wrong
number of arguments (when the function takes a fixed number
of arguments), or passing a wrong type of argument to a func-
tion,
What do you do when a function does not return anything,
or when it does not accept any parameters? To answer this, we
have to describe a new data type that is part of the ANSI C pro-
posal.
pointers that can point to any type of data. For example, if a func-
tion does not return anything, say the exit function in the library,
it can be declared as
void exit(int);
On the other hand, if a function does not accept any formal pa-
rameters, its list of arguments is represented by the word void:
int getchar(void);
Expressions in C
An “expression” in C is a combination of variables, function
calls, and operators that result in a single value. For example,
(strlen(a_string) * sizeof(char) + 1)
Arithmetic Operators
Bitwise Operators
~ Bitwise complement ~X flip 1 bits to 0 and 0 bits to 1
& Bitwise AND xay bitwise AND of x and y
} Bitwise OR Xly bitwise OR of x and y
A Bitwise exclusive OR xy value with 1s at bits where
corresponding bits of x and y
differ
«« Left shift xX «C4 X shifted to the left by 4 bit
positions
»» Right shift x)>)4 X Shifted to the right by 4 bit
positions
4—The ANSI C Language 27
Miscellaneous Operators
Operator Precedence
Typically, you use several operands and operators in many state-
ments of your program. For example, if you write
*ptr(2]
is the result the value to which ptr[2] points, or is it the third ele-
ment from the location whose address is in ptr? To determine
this, you need to know the order in which operators are applied.
This is specified by the operator’s ‘precedence,’ which is sum-
marized in Table 4-3. Operators with highest precedence—those
that are applied first—are shown first. The order in which opera-
tors at the same level get evaluated (‘‘associativity’’) is also
shown. If you consult the table, you will find that the [ ]operator
has precedence over the * operator. So in our example, ptr[2] is
Statements in C
Statements control the flow of execution of a C program. A
“statement” consists of keywords, expressions, and other state-
ments. Each statement ends with a semicolon. Here are some
simple C statements:
i /* a null statement */
x=y=2;
Xt+7
_ continue;
‘Example:
- do-while
loop —
Example:
4—The ANSI C Language 29
Function Definitions
The building blocks of C programs, “functions” are indepen-
dent collections of declarations and statements you mix and
match to create stand-alone applications in C. Each C program
has at least one function: the main function. The library speci-
fied in ANSI C consists mainly of functions (in addition to quite a
few macros). For the most part, developing software in C is a
matter of writing functions.
{
if ( a >= b)
return (a);
else
return (b);
}
Pointers to Functions
A function cannot return an array or another function directly.
Also, an array cannot have functions among its elements. This is
not a problem because you can always use pointers to functions
in places where functions themselves are not allowed. Declaring
a pointer to a function is similar to declaring a pointer to a vari-
32 =An Overview of ANSI C
In this example, the first element of the array funclist is even ini-
tialized to the function process3double, which is defined in our
previous example.
ANSI C Keywords
Finally, here is a list of all the keywords of ANSI C. Individual
_teference entries for the keywords follow.
> auto
Purpose
Use the auto storage class specifier to declare temporary vari-
ables. These are created when entering a block statement and
destroyed at exit. Local variables of a function have the auto
storage class by default.
auto
4—The ANSI C Language 33
Example
In this example, the variables 7, limit, and sum are created only
when the if statement is ttue— when the user presses a C.
#include <stdio.h> main)
{
Tint cs
c = getchar();
if(c == 'C')
{
auto int i, limit, sum;
printf(''Sum from 1 to ?!"');
scanf(" Z%d",&limit);
/* Compute sum from 1 to limit */
for(i=0, sum=0; i <= Limit; sum += i, i++);
printf('\nSum from 1 to %d = %d\n'', Limit, sum);
See Also
break <4
Purpose
Use break to exit from the innermost do, while, orfor loop. It is
also used to exit from a switch statement.
Example
This code fragment adds the numbers from 1 to 10 in an endless
loop. It uses break to exit the loop.
sum = 0;
ij = 0;
while(1)
nf
sum += 1;
Ticteste
if(i > 10) break;
}
See Also
break
34 An Overview of ANSI C =
———___e
Pm case
Purpose
Use case to label cases in a switch statement.
Example
See switch for an example.
See Also
default, switch
> char
Purpose
Use char to declare character variables and arrays.
Example
The example declares a character, a pointer to a char, and an ar-
ray of characters.
.char c, *p_c, stringl80);
See Also
> const
Purpose
Use the const qualifier to indicate that the variable that follows
may not be modified by the program. This means that you can-
not assign a value to that variable, increment it, or decrement it.
Example
This example declares that the value of x, the contents at the lo-
cation whose address is p_i, and the pointer p_.c_i must not
be changed by the program’s code.
const short x; /* x is constant */
const int *p_i; /* *p_i is constant */
int *const p_c_i; /* pointer p_c_i is constant */
const
4—The ANSI C Language 35
See Also
volatile
LN i ia a a cae ng hol
continue 4
Purpose
Example
This for loop is skipped when 7 is 5, giving us the sum of the
numbers from 1 to 10, excluding 5.
for(i=0, sum=0; i <= 10, i++)
{
if(i == 5) continue;
sum += i;
}
See Also
for, if, while
default <4
Purpose
Use default as the label in a switch statement to mark code to be
executed when none of the case labels match the switch expres-
sion.
Example
See switch for an example.
See Also
case, switch
do<4
Purpose
Use do with while to form iterative loops of the kind
36 =An Overview of ANSI C
do statement while(expression);
Example
The do loop shown here continues until 7 exceeds 10.
do
{
sum += 7;
a
}
while(i >= 10);
See Also
for, if, while
> double
Purpose
Use double to declare double-precision floating-point variables
and arrays.
Example
This example declares a double, a pointer to a double, and an
array of doubles.
double d, *p_d, dvars[80];
See Also
> else
Purpose
else
4—The ANSI C Language 37
Example
See if for an example.
See Also
ai
enum <4
Purpose
Use enum to define an integral data type that can take its values
from a list of enumerated constants. The declaration is of the
form
Example
This code makes traffic_signal the name of an enumerated
type, and it declares signal_1 as a variable of that type and
p—signal as a pointer to traffic__signal. You can see that the def-
inition of the enum also enables you to initialize the entries in
the enumerated list.
enum traffic_signal {red = 10, yellow = 20, green = 30};
enum traffic_signal signal_1, *p_signal;
See Also
typedef
extern <4
Purpose
Use extern to tell the compiler that a variable or a function is de-
fined in another module (a separate file) and that you want to use
it in the current module. The variable or function cannot have
been declared with the static or extern qualifiers.
extern
38 An Overview of ANSI C
Example
In this example the variables current _state and state_table are
shared among FILE 1 and FILE 2. They are defined in FILE 1 and
declared to be extern in FILE 2.
(ke ap aS 1 */
int current_state, state_table[MAXSTATE] [MAXSYMB];
extern void next_state(int in_symbol);
main()
{
int in_symbol;
current_state = 0;
next_state(in_symbol);
[te 2 Se bal3 2 */
void next_state(int in_symbol)
a
extern int current_state, state_table[MAXSTATE] [MAXSYMB];
if ( current_state ==0).
current_state = state_table[current_state]Lin_symbol];
_ See Also
static
> float
Purpose
Use float to declare single-precision floating-point variables and
arrays. :
Example
This example declares a float, a pointer to a float, and an array of
floats.
float f, *p_f, fvars{100];
See Also
float
4—The ANSI C Language 39
for <4
Purpose
Use for to form iterative loops of the type
for (expression_1; expression_2; expression_3) statement
Example
The for loop shown here adds the numbers from 1 to limit, all
inside the third expression in the for loop.
See Also
break, continue, if, switch
goto <@
Purpose
Use goto to jump unconditionally to a label in the current func-
tion.
Example
if (system_price > 6000.0) goto TooExpensive;
TooExpensive:
seek_alternative(;
See Also
break, continue
if <
Purpose
Use if to excute code only when certain conditions hold. You
can use if alone or with else to form constructs such as
if
40 An Overview of ANSI C
if ( expression ) statement
or
if ( expression ) statement_1 else statement_2
Example
This example shows how to use if and else to pick the smaller of
two variables.
: if ( x <= y) smaller = x;
else smaller = y;
See Also
else
> int
Purpose
Use int to declare integer variables and arrays. To declare an inte-
" ger of a specific size, use the size qualifiers short and long. The
size of an int is implementation dependent but it is guaranteed to
be larger than a short.
Example
int i, xf100);
See Also
> long
Purpose
Use long as a size qualifier for int and unsigned int variables.
Note that /ong alone means signed long int. A long qualifier indi-
cates that the integer data type is 4 bytes in size.
Example
This example shows the declaration of a Jong int and an un-
signed long int.
long
4—The ANSI C Language 41
long filepos;
unsigned long timer_tick;
See Also
register <4
Purpose
Use register as a storage Classifier for integer data types to inform
the compiler that access to that integer should be as fast as pos-
sible. (Some compilers may use a CPU register to store that vari-
able.)
Example
register int 1;
See Also
return <<
Purpose
Use return to terminate execution of the current function and
return control to the caller. If the function returns a value, use
the statement return (expression) to return the value repre-
sented by the <expression).
Example
This function returns the maximum of two integers.
int findmax(int a, int b)
{
if(a >= b)
return a;
else
return b;
}
See Also
break, continue, goto
return
42 An Overview of ANSI C e
> short
Purpose
Use short as a size qualifier for int and unsigned int variables.
Note that short alone means signed short int. A short qualifier
indicates that the integer data type is 2 bytes in size.
Example
This example shows the declaration of a short int and an un-
signed short int.
short offset;
unsigned short array_index;
See Also
> signed
Purpose
_Use the signed qualifier to indicate that data stored in an integer
type (int or char) is signed. For example, a signed char can take
values between —127 and +127 whereas an unsigned char can
hold values from 0 to +255. The int and char types are signed by
default.
Example
int i; /* signed by default */
Signed long int x;
See Also
char, double, float, int, long, short, unsigned
> sizeof
Purpose
Use the sizeof operator to get the size of a data element in bytes.
You can use it to determine the size of a structure, for example,
so that you can call calloc to allocate an array of them. Another
use of sizeofis to compute the number of elements in an array.
sizeof
4—The ANSI C Language 43
Example
This code fragment uses sizeof to get the size of a structure in
order to use it as an argument to calloc. It also uses sizeof to ini-
tialize the count of elements in an array.
struct mytype
{
char firstname(20];
char lastname(20];
};
short offsets{] = {-1, 10, 20, 32, 48};
short n_offsets = sizeof (offsets) /sizeof(offsets[0]);
See Also
typedef
static <¢
Purpose
Use static to localize the declaration of a data item or a function
to a program module (file). You can use this to “hide” functions
and data from other modules. Static variables are stored perma-
nently; they retain their values for the life of the program.
Example
In this example each file has its own copy of the variable current
_ index. Each copy is initialized once and each retains its last-
stored value throughout the execution of the program.
[xe (Pct EOE 1 */
static int current_index = 0;
main()
{
current_index = 1;
}
(ke (pei 1G 13 2 */
static int current_index = 0;
void some_function(void)
{
jf ( current_index ==0) ..
current_index = 2;
static
44 An Overview of ANSI C
See Also
auto, extern
> struct
Purpose
Use struct to group related data items together, and give the
group a name to which you can refer later. The general form is
struct structure_name
x
type item_1;
type item 2;
Ds
struct structure_name struct_1, struct_2;
Example
This example defines a structure to be used in a linked list. It
contains several members, including one that is a pointer to it-
self.
struct node
{
int node_type;
char node_namel16];
struct node *next;
3;
struct node *p_node, first_node;
See Also
union
SS
SS
> switch
Purpose
Use the switch statement to perform a multibranching that de-
pends on the value of an expression. The syntax is
switch (expression) statement
switch
4—The ANSI C Language 45
Example
The switch statement here executes different routines depend-
ing on the value of command. Note the use of break statements
to keep the execution from falling through one case label to an-
other.
switch (command)
{
case 'Q': exit(0);
case 'C': connect();
break;
case 'S': sendfile();
break;
case 'P': newparams();
break;
case '?': showparams();
break;
case 'H': printf (helplist);
break;
default: printf('"'Unknown command! \n"");
}
See Also
break, case, default
typedef <
Purpose
Use typedefto give anew name to an existing data type. The syn-
tax is
typedef existing_type new_name;
Example
See the tutorial section for examples that use typedef to simplify
the declaration of complex data types.
See Also
enum
typedef
46 = An Overview of ANSI C
> union
Purpose
Use union to allocate storage for several data items at the same
location. The declaration of union is like that of struct, except
that in a wnion all data items in the declaration share the same
storage location.
Example
This example declares a wnion that stores a short in a location
with an array of two characters. Each individual byte of the short
stored in the union x can be accessed by x. bytes/[O] and x.
bytes[1].
union short_u
{
short sh_val;
char bytes(2];
};
union short_u x;
See Also
struct
> unsigned
Purpose
Use the unsigned qualifier with integer data types (char, int,
short int, and long int) to tell the compiler that the variable will
store non-negative values only. This effectively doubles the max-
imum value that can be stored in that variable. Another useful
feature is that arithmetic involving unsigned integers cannot
overflow because all operations are performed modulo a num-
ber that is one greater than the largest value that can be repre-
sented by that unsigned type.
Example
Here are some declarations of unsigned variables.
unsigned char data(1000];
unsigned long file_pos;
unsigned i; /* equivalent to unsigned int i */
See Also
unsigned
4—The ANSI C Language 47
SibENON SEE SS el
void <4
Purpose
Use the data type void to indicate the nonexistence of a return
value or of arguments in a function definition and prototype.
You can use void * to declare a pointer to any type of data ob-
ject.
Example
void a_function(void *buffer);
int get_something(void);
extern void *p_buf;
See Also
volatile <4
Purpose
Use the volatile type qualifier to inform the compiler that the
variable that follows may be modified by factors outside the con-
trol of your program. For example, the register in the real-time
clock in your system is such a variable. The volatile qualifier
warns the compiler that actions performed on volatile data must
not be “optimized out.” You can use the qualifier const together
with volatile to qualify objects that must not be changed by
your program, yet may change due to external factors.
Example
This code shows the declaration of the register in a real-time
clock. It says that our code cannot change the content (*p_rt_
clock), but that the content may change by itself. We are free,
however, to modify the pointer p_rt_clock to point to another
long int.
const volatile long *p_rt_clock = CLOCK_ADDRESS;
See Also
const
volatile
48 An Overview of ANSI C
> while
Purpose
Use the while statement to construct loops such as
while (expression) statement
Example
This while loop adds the numbers 1 through 10.
sum = 0;
i = 0;
while(i <= 10)
{
sum += i;
atte
}
See Also
Introduction
The proposed ANSI standard for C defines all aspects of the lan-
guage, including the library that makes C unique. The proto-
types of the library routines and all necessary preprocessor
constants and data structures are defined in a set of standard
header files. Tables 5-1 and 5-2 show the minimal contents ofthe
library that must be present in an ANSI standard-conforming C
compiler. Table 5-1 lists the standard header files and summa-
rizes their contents. Table 5-2 lists all macros and data types
defined in the standard header files in ANSI C. Almost all com-
mercial C compilers have additional routines in their libraries.
For example, the Turbo C 1.5 and Microsoft C 5.1 compilers,
available for MS-DOS systems, include library routines for
graphics and access to DOS functions and even the standard
header files have additional routines in them.
Header File
Name Description
assert.h Defines the assert macro and NDEBUG symbol. Used for program
diagnostics.
ctype.h Declares character classification and conversion routines.
ermo.h Defines macros for error conditions, EDOM and ERANGE, and the
integer variable errno.
float.h Defines symbols for the maximum and minimum values of floating-
point numbers.
limits.h Defines symbols for the limiting values of all integer data types.
locale.h Declares functions necessary for customizing a C program to a
particular locale. Defines the /conv structure.
math.h Declares the math functions and the HUGE VAL constant.
49
50 =An Overview of ANSI C
setjmp.h Defines the jmp__ buf data type used by the routines setjmp and
longjmp.
signal.h Defines symbols and routines necessary for handling exceptional
conditions.
stdarg.h Defines the macros that facilitate handling variable-length argument
lists.
stddef.h Defines the standard data types ptrdiff_t, size_t, wehar_t, the
symbol NULL, and the macro offsetof.
stdlib.h Declares the utility functions such as the string conversion routines,
random number generator, memory allocation routines, and process
control routines.
string.h Declares the string manipulation routines.
time.h Defines data type time__t, the tm data structure, and declares the
time functions.
Macro or Where
Data Type Defined Description
Macro or Where
Data Type Defined Description
Macro or Where
Data Type Defined Description
&
seg
7 y
==
. ye
i
ANSI C Files and 1/0
Streams and Files in ANSI C
Introduction
The C programming language has no built-in capability to per-
form I/O. This is the responsibility of the library accompanying
your C compiler. Fortunately, the ANSI standard for C also speci-
fies the I/O functions that must be present in a standard-con-
forming compiler.
Streams
The concept of a “stream” as a sequence of bytes of data is uni-
versal to all I/O in C and UNIX. While it is customary to use the
terms “‘stream” and “file” synonymously, you could better liken
a file to a faucet and a stream to a hose attached to get water (data)
from the faucet. All I/O operations in ANSI C, whether to or from
a disk file or a hardware port, are mapped to a stream.
59
60 ANSI C Files and |/0
LF). Thus, reading from an MS-DOS file using a text stream will
involve altering the CR-LF to a single newline character.
A “binary” stream, on the other hand, allows you to access
the data from an underlying file or device unchanged. To under-
stand and use the data from a binary stream you must know what
was stored in the file in the first place. After all, a 4-byte value in
the file could be a long integer or it could be a float variable. It
could even be two short integers. When you know how the bi-
nary file was written, reading from it is straightforward. For ex-
ample, if you write 1,000 short integer values to a binary file
from a 2,000-byte buffer in memory, each 2-byte value you later
read from the file represents a short integer—a perfect match.
Files
In ANSI C, a “file” represents the source of data. It can be an
actual file stored on a disk, a RAM disk, CD ROM, or some exter-
nal media. A file must be able to receive or impart a stream of
bytes; physical storage need not underlie a file as is shown in Fig-
ure 6-1A. Viewed in this manner, the keyboard, the serial com-
munications port, the display screen are all files—precisely the
“model” used by the file I/O routines in ANSI C.
a data
8
(A)
Serial port
RAM disk
(C)
Sector of disk
Base of Current
buffer character
Buffer in
memory 1/0 routines
interact
with buffer
File on disk
BUFSIZ This constant defines the size of each buffer associated with a
Stream. It is defined in stdio.h.
FILENAME MAX Maximum length of file name string.
FOPEN _ MAX Minimum number of files that the underlying operating system
guarantees can be opened simultaneously. This must be at
least eight, including the preopened streams stdin, stdout, and
stderr.
- EOF This constant denotes the end-of-file condition and is defined
in stdio.h as a negative number.
L_tmpnam This constant is the length of a character array large enough to
hold temporary file names generated by tmpnam.
NULL A constant defined in stdio.h to signify a null pointer.
TMP_MAX This constant denotes the number of file names that can be
generated by tmpnam.
Routine — Description
String 1/0
If you think of files as a stream of bytes, the data sources or desti-
nations do not have to be disk files or devices; they can also be
buffers in memory. A group of ANSI C I/O routines provide the
capability to read from and write to arrays of characters
(“strings’’). These routines allow you to format data and place
the result in a string or to get characters from a string and convert
the characters to internal values. This is often convenient be-
cause yOu Can prepare a string to be output by routines that have
no formatting capability. Table 6-4 lists the three string I/O rou-
tines according to the task they perform.
This formatted read statement reads the three values with any
number of blank spaces between them. Note that the format
code meant for the float variable is different from that for the
double. The %f code tells scanf to convert the string into the
internal representation of a float variable. Adding the qualifier |
between the % and the f tells scanf to use the internal represen-
tation of a double instead of a float.
Like printf, scanf is meant for formatted input from the
stream stdin. The ANSI C I/O library also includes fscanf for for-
matted input from a file and sscanf for formatted input from aC
string. These routines use the same formatting commands as
scanf. The reference entry on scanf gives more details on the
formatting options.
Further Reading
The standard I/O routines are covered in almost any book on C.
Prata’s book' is a good place to start. The Waite Group’s refer-
ence guides for Microsoft C* and Turbo C? detail the I/O routines
offered by these implementations of C.
1. Stephen Prata, The Waite Group's Advanced C Primer++,
Howard W. Sams & Company, Indianapolis, IN, 1986, 502
pages.
2. Nabajyoti Barkakati, The Waite Group's Microsoft C
Bible, Howard W. Sams & Company, Indianapolis, IN, 1988,
808 pages.
3. Nabajyoti Barkakati, The Waite Group's Turbo C Bible,
Howard W. Sams & Company, Indianapolis, IN, 1988, 900
pages.
Fs 144reset
ait rab
i
4
= ®
é i
‘
™~
f “i
ANSI C File 1/0 Routines
clearerr <4
Purpose
Use clearerr to reset the error and end-of-file indicators of the
stream specified by the stream pointer stream.
Syntax
#include <stdio.h>
void clearerr(FILE *stream);
FILE *stream; Pointer to stream whose error flag is being cleared
Example Call
clearerr(outfile);
See Also
ferror, feof
Example
See Example 7-1 on page 99. Line 44 in that example uses
clearerr to reset the error flag after an error occurs during file
1/O.
fclose <4
Purpose
Use fclose to close the stream specified by stream. If the stream
was open for writing, the content of the buffer associated with the
69
70 ANSI C Files and I/0
Syntax
#include <stdio.h>
int fclose(FILE *stream);
FILE *stream; Pointer to stream to be closed
Example Call
fclose(infile);
Returns
If the stream was successfully closed, feof returns a zero; other-
wise, it returns EOF.
See Also
fopen, fflush
Example
Lines 57 and 58 in Example 7-1 call fclose to close files before
exiting the program.
> feof
Purpose
Use feof to determine whether stream’s end-of-file indicator is
set. When you get an error return from a read operation, you can
call feof to determine if the error occurred because you tried to
read past the end-of-file.
Syntax
#include <stdio.h>
int feof(FILE *stream);
FILE *stream; Pointer to FILE data structure associated with the stream
whose status is being checked
Example Call
if (feof(infile) != 0) printf("File ended\n");
Returns
feof
7—ANSI C File 1/0 Routines 71
See Also
Example
Line 42 of Example 7-1 uses feof to check for end-of-file.
Si ena
ecaaen pis ede
Som gue rly se
ferror <4
Purpose
Use ferror to determine if the error indicator is set for the speci-
fied stream.
Syntax
#include <stdio.h>
int ferror(FILE *stream);
FILE *stream; Pointer to FILE data structure associated with the stream
whose status is being checked
Example Call
if (ferror(infile) != 0) printf("Error detected\n");
Returns
See Also
clearerr, feof
Example
Line 40 of Example 7-1 uses ferror to check the error indicator of
a stream.
fflush <4
Purpose
Use the fflush function to flush the current contents of the
buffer associated with the stream specified by stream. If the file
is open for write operations, the flushing involves writing the
contents of the buffer to the file. Otherwise, the buffer is
cleared. If stream is NULL, all open streams are flushed.
fflush
72. ANSI C Files and 1/0
Syntax
#include <stdio.h>
int fflush(FILE *stream);
FILE *stream; Pointer to stream whose buffer is being flushed
Example Call
fflush(stdin);
Returns
If the flushing is successful, fflush returns a zero. In case of an
error, it returns the constant EOF defined in stdio.h.
See Also
fopen, fclose, setbuf, setvbuf
Example
See Example 7-2 at the end of this chapter. Line 90 in that ex-
ample uses {flush to flush stdin’s buffer to ensure that a new
command line is read.
> fgetc
=
Purpose
Use fgetc to read a single character from the stream specified by
the pointer stream. The character is read from the current posi-
tion in the stream. After reading the character, the current posi-
tion advances to the next character.
Syntax
#include <stdio.h>
int fgetc(FILE *stream);
FILE *stream; Pointer to stream from which a character is to be read
Example Call
char_read = fgetc(infile);
Returns
See Also
fgetc
7—ANSI C File 1/0 Routines 73
eee
fgetpos <4
Purpose
Use fgetpos to get and save the current position indicator of the
stream specified by the argument stream in the fpos_t data ob-
ject whose address is in current__pos. This value is used by the
companion function fsetpos to reposition the stream at the time
of the call to fgetpos.
Syntax
#include <stdio.h>
int fgetpos(FILE *stream, fpos_t *current_pos);
FILE *stream; Pointer to stream whose current position is requested
Example Call
fgetpos(infile, &curpos);
Returns
See Also
fsetpos
fgets <4
Purpose
Use the fgets function to read a line from the stream specified by
stream. The line is read into the character array string until a
newline (\n) character is encountered, an end-of-file condition
occurs, or the number of characters read reaches one fewer than
the value given in the argument maxchar. A null character is
written to string immediately after the last character.
Syntax
#include <stdio.h>
char *fgets(char *string, int maxchar, FILE *stream);
char *string; Pointer to buffer in which characters will be stored
fgets
74. ANSI C Files and 1/0
Example Call
fgets(buffer, 80, infile);
Returns
See Also
gets, fputs, puts
Example
Line 38 in Example 7-1 calls fgets to read a line from a file.
> fopen
Purpose
Use fopen to open the file whose name is specified in the string
filename and associate a stream with it. The argument ac-
cess__mode contains one of the strings listed in Table 7-1.
access__ mode
String Interpretation
aie Open a text file for reading. Fail if file does not exist.
“w" If file exists, open and truncate it to zero length. Otherwise,
create the file and open it for writing in the text mode.
a’ Open text file for appending—writing at the end of file. Create
file if it does not exist.
“ilo Same as “r”—but binary mode.
“wb” Same as “w’—but binary mode.
“ab” Same as “a”—but binary mode.
(isa Open text file for updating—reading as well as writing.
“w+” If file exists, open it and truncate it to zero length. Otherwise,
create it and open it for updating.
rahi Open text file for appending. Create file if it does not exist.
“rb” or “rb” Open binary file for updating.
“w+b” or “wb+” If file exists, truncate to zero length. Otherwise, create a
binary file for update operations.
“a+b” or “ab+” Open or create binary file for appending.
fopen
7—ANSI C File 1/0 Routines 75
Syntax
#include <stdio.h>
FILE *fopen(const char *filename, const char *access_mode);
const char *filename; Name offile to be opened
Example Call
input_file = fopen("data.in", "rb!');
Returns
See Also
fclose, freopen, setbuf, setvbuf
Example
Lines 19 and 29 in Example 7-1 show calls to fopen.
fprintf <
Purpose
Use the fprintf function to format and write character strings
and values of C variables to the stream specified by the argument
stream. See the reference entry for printf for a description of the
argument format_ string.
Syntax
#include <stdio.h>
int fprintf(FILE *stream, const char *format_string,...);
FILE *stream; Pointer to stream to which the output goes
Example Call
fprintf(resultfile, "The result is %f\n"', result);
fprintf
76 ANSI C Files and 1/0
Returns
The fprintf function returns the number of characters it has
printed. In case of error, it returns a negative value.
See Also
printf, vfprintf, vprintf, sprintf, vsprintf
Example
Line 62 in Example 7-2 uses fprintf to print an error message to
the stream stderr.
> fputc
Purpose
Use fputc to write the character c to the stream specified by
stream.
Syntax
H#include <stdio.h>
int fputc(int c, FILE *stream);
nt ce Character to be written
Example Call
fputc('X', p_datafile);
Returns
See Also
> fputs
Purpose
Use the fputs function to write the C string given by string to the
stream specified by stream.
fputs
7—ANSI C File 1/0 Routines 77
Syntax
#include <stdio.h>
int fputs(const char *string, FILE *stream);
const char *string; Null-terminated (\0) character string to be output
Example Call
fputs(''Sample Input Data’, p_datafile);
Returns
See Also
Example
Line 52 in Example 7-1 uses fputs to write a line to a file.
fread <4
Purpose
Use fread to read the number of data items specified by count,
each of a size given by the argument size, from the current posi-
tion in stream. The current position of stream is updated after
the read.
Syntax
#include <stdio.h>
size_t fread(void *buffer, size_t size, size_t count,
FILE *stream);
void *buffer; Pointer to buffer where fread stores the bytes it reads
FILE *stream; Pointer to stream from which data items are to be read
Example Call
numread = fread(buffer, sizeof(char), 80, infile);
Returns
fread
78 ANSI C Files and I/0
See Also
fopen, fwrite, fclose
Example
Line 105 in Example 7-2 reads a record from a file using fread.
> freopen
Purpose
Use freopen to close stream, open another file whose name is in
the string filename, and attach stream to it. For example, you
can use freopen to redirect I/O from the preopened file stdout to
a file of your choice. See fopen for a description of the argument
access __mode. The error indicator of stream will be cleared after
the reopening.
Syntax
#include <stdio.h>
FILE *freopen(const char *filename, const char *access_mode,
FILE *stream);
const char *filename; Name offile to be reopened, including drive
and directory specification
Example Call
freopen("output.txt", "w'', stdout); /* Redirect stdout to a
file */
Returns
See Also
fopen, fclose
freopen
7—ANSI C File 1/0 Routines 79
Ao DRL ee i en ee
fscanf <
Purpose
Use the fscanf function to read characters from stream, convert
them to values according to format specifications embedded in
the argument format_ string, and store the values in C variables
whose addresses are provided in the variable-length argument
list. See scanf for more details on the argument format_string.
Syntax
#include <stdio.h>
int fscanf(FILE *stream, const char *format_string,...);
FILE *stream; Pointer to the stream from which reading will occur
Example Call
fscanf(infile, "Date: %d/%d/%d"", &month, &day, &year);
Returns
The fscanf function returns the number of input items that were
successfully read, converted, and saved in variables. The count
does not include items that were read and ignored. If an end-of-
file is encountered during read, the return value will be equal to
the constant EOF (defined in stdio.h).
See Also
scanf, sscanf
fseek <4
Purpose
Use the fseek function to reposition stream to the location speci-
fied by offset with respect to the argument origin. The valid val-
ues of origin are the following constants:
Origin Interpretation
fseek
80 ANSI C Files and 1/0
Syntax
#include <stdio.h>
int fseek(FILE *stream, long offset, int origin);
FILE *stream; Pointer to stream whose current position is to be set
Example.Call
fseek(infile, OL, SEEK_SET); /* Go to the beginning */
Returns
See Also
fgetpos, fsetpos, ftell
Example
Line 99 in Example 7-2 uses fseek to skip the file header when
reading records from a file.
> fsetpos
Purpose
Use fsetpos to set the position where reading or writing will take
place in stream. The new position is specified in an fpos_t data
object whose address is in current_pos. For file position, use
the value obtained by an earlier call to fgetpos.
Syntax
#include <stdio.h>
int fsetpos(FILE *stream, const fpos_t *current_pos);
FILE *stream; Pointer to stream whose current position is to be set
Example Call
fgetpos(infile, &curpos);
Returns
fsetpos
7—ANSI C File |/0 Routines 81
See Also
fgetpos
ae
ee
ftell <4
Purpose
Use frel/ to obtain the current position of stream. The position is
expressed as a byte offset from the beginning of the file.
Syntax
#include <stdio.h>
long ftell(FILE *stream);
FILE *stream; Pointer to stream whose current position is to be
returned
Example Call
curpos = ftell(infile));
Returns
See Also
Example
Line 104 in Example 7-2 shows how /tel/ can be used to get the
current position in the file.
fwrite <
Purpose
Use the fwrite function to write the number of data items speci-
fied by count, each of a size given by size, from buffer to the
current position in stream. The current position of stream is up-
dated after the write.
Syntax
#include <stdio.h>
fwriie
82 ANSI C Files and 1/0
Example Call
numwrite = fwrite(buffer, sizeof(char), 80, outfile);
Returns
See Also
fopen, fread, fclose
Example
Lines 69 and 76 in Example 7-2 illustrate how fwrite is used to
*write binary data to a file.
> getc
Purpose
Use the gefc macro to read a single character from stream. Ex-
cept that it is implemented as a macro, getc is identical to fgetc.
So you should not provide it an argument that might cause side
effects (see tutorial in Chapter 3).
Syntax
H#Hinclude <stdio.h>
int getc(FILE *stream);
FILE *stream; Pointer to stream from which a character is to be read
Example Call
in_char = getc(p_txtfile);
Returns
getc
7—ANSI C File 1/0 Routines 83
See Also
Purpose
Use the getchar macro to read a single character from the pre-
opened file stdin, which is normally connected to your key-
board input. Note that getchar is identical to getc with stream set
to stdin.
Syntax
#include <stdio.h>
int getchar(void);
Example Call
c = getchar();
Returns
The getchar macro returns the character read from stdin as an
integer value. In case of an error the return value is equal to the
constant EOF.
See Also
fgetc, fputc, getc, putc, putchar
Example
Line 87 in Example 7-2 uses getchar to read a single character
command from stdin.
gets <4
Purpose
Use gets to read a line from the standard input file stdin into the
string buffer. The reading continues until gets encounters a
newline character or end-of-file. At this point, it replaces the
newline character with a null character (\O) and creates a string.
You must allocate room for the buffer in which the string will be
stored. Note that fgets performs similarly but, unlike gets, it re-
tains the newline character in the final string.
gets
84 ANSI C Files and |/0
Syntax
#include <stdio.h>
char *gets(char *buffer);
char *buffer; Buffer where string will be stored
.
Example Call
gets(command_line);
Returns >
If successful, gets returns buffer. Otherwise, it returns a NULL.
See Also
fgets, fputs, puts
Example
Lines 15 and 25 in Example 7-1 call gets to read the user’s input.
> printf
Purpose
Use printfto write character strings and values of variables, for-
*matted in a specified manner, to the standard output file stdout
(normally the screen). The value of each argument is formatted
according to the codes embedded in the string format_ string.
The formatting command for each variable consists of a percent
sign (%) followed by a single letter denoting the type of variable
being printed. The complete format specification is of the form:
% |Flags][(Width].[{Precision][Size][Type]
Table 7-2 summarizes each component of the format string. Ta-
bles 7-3 and 7-4 explain the Flag and Type fields, respectively.
Syntax
#include <stdio.h>
int printf(const char *format_string,...);
const char *format_string; A character string that describes the
format to be used
Example Call
printf('The product of %d and %d is %d\n", x, y, x*y);
Returns
printf
7—ANSI C File 1/0 Routines 85
Type (Required) A letter to indicate the type of variable being printed. Table 7-
4 lists the characters and their meanings.
Flag Meaning
printf
86 ANSI C Files and 1/0
printf
7—ANSI C File 1/0 Routines 87
See Also
Example
The printf function is used in almost every C program. Example
7-1. uses it in lines 13, 21, 24, 31, and 55.
putc <
Purpose
Use the putc macro to write a single character c to stream. Ex-
cept that it is implemented as a macro, putc is equivalent to
fpute.
Syntax
#include <stdio.h>
int putc(int c, FILE *stream);
intace Character to be written
Example Call
putc('*', outfile);
Returns
The putc macro returns the character written. A return value of
EOF indicates an error. Call the ferror function to determine if an
error occurred.
See Also
fgetc, fputc, getc, getchar, putchar
putchar <4
Purpose
Use the putchar macro to write the character c to the preopened
stream stdout which has been initially connected to your dis-
play. The putchar macro is equivalent to putc with the second
argument set to stdout.
putchar
88 ANSI C Files and I/0
Syntax
#include <stdio.h>
int putchar(int c);
antes Character to be written
Example Call
putchar('?');
Returns
See Also
> puts
Purpose
Use puts to Output string to the standard output stream stdout.
The terminating null character (\0) is replaced by a newline (\n)
»in the output.
Syntax
#include <stdio.h>
int puts(const char *string);
const char *string; Stringto be output
Example Call
puts("Do you really want to quit? ");
Returns
See Also
fgets, fputs, gets
Example
Lines 41 and 43 in Example 7-1 use puts to print error messages
to stdout.
puts
7—ANSI C File 1/0 Routines 89
SL
TD
remove <
Purpose
Syntax
#include <stdio.h>
int remove(const char *file_name);
const char *file_name; Name offile to be deleted
Example Call
remove("'/usr/tmp/tmp01234"); /* Delete temporary file */
Returns
See Also
rename
rename <@
Purpose
Use rename to change the name ofa file from oldname to new-
name.
Syntax
#include <stdio.h>
int rename(const char *oldname, const char *newname) ;
const char *oldname; Current file name
Example Call
/* Copy "'test.exe’ from /usr/tmp to /usr/bin and give it a new
name */
rename("'/usr/tmp/test.exe", '"'/usr/bin/grview.exe") ;
Returns
If rename is successful, it returns a zero. In case of an error, it
returns a nonzero value.
See Also
fopen, fclose, remove
rename
90 ANSI C Files and 1/0
> rewind
Purpose
Use the rewind function to set the current read or write position
associated with stream to the beginning of the file. The rewind
clears the end-of-file or error indicator of stream. Calling the re-
wind function is equivalent to calling (void) fseek(stream, OL,
SEEK __SET).
Syntax
#include <stdio.h>
void rewind(FILE *stream);
FILE *stream; Pointer to stream whose position is to be set to the
beginning of the file
Example Call
rewind(input_file);
See Also
fseek
>
Pm scanf
Purpose
Use scanf to read characters from the standard input file stdin
and convert the strings to values of C variables according to the
format specified in the string format_ string. For each variable’s
address included in the argument list to scanf there must be a
format specification embedded in the format_string. The for-
mat specification for each variable has the form:
%[*][Width]{Size][
Type]
Table 7-5 summarizes the purpose of each field in the format
specification used by scanf. Further details are provided in Table
7-6.
Normally strings read using the %s format are assumed to
be delimited by blank spaces. When you want to read a string
delimited by any character other than those ina specific set, you
can specify the set of characters within brackets and use this in
place of the letter s in the format specification. On the other
hand, if the first character inside the brackets is a caret (*), the set
is assumed to show the characters that terminate the string.
Thus, for example, %[/’\” will read a string delimited by single
or double quote characters.
scanf
7—ANSI C File 1/0 Routines 91
Type (Required) A letter that indicates the type of variable being read. Table 7-6
lists the characters and their meanings.
scanf
92 ANSI C Files and |/0
Syntax
#include <stdio.h>
int scanf(const char *format_string,...);
const char *format_string; Character
string that describes the
R format to be used
Example Call
scant("' %d:%d:%d", &hour, &minute, &second);
Returns
The scanf function returns the number of input items that were
successfully read, converted, and saved in variables. This does
not include the items that were read and ignored. A return value
equal to the constant EOF (defined in stdio.h) means that an end-
of-file was encountered during the read operation.
See Also
fscanf, sscanf
> setbuf
Purpose
setbuf
7—ANSI C File 1/0 Routines 93
Syntax
#include <stdio.h>
void setbuf(FILE *stream, char *buffer);
FILE *stream; Pointer to stream whose buffer is being set
Example Call
setbuf(infile, mybuffer);
See Also
setvbuf
setvbuf <
Purpose
Use the setubuf function to assign buffer, of a size buf _size, to
stream. By specifying appropriate constants for the argument
buf_mode, you can control the type of buffering to be used or
turn off the buffering for stream. If buf__mode is _IOFBF, the
I/O operations with the stream will be fully buffered. If it is _
IOLBF, the buffering will be done one line at a time. Setting buf
_mode to _IONBEF causes I/O to be unbuffered.
Syntax
#include <stdio.h>
int setvbuf(FILE *stream, char *buffer, int buf_mode,
size_t buf_size);
FILE *stream; Pointer to stream whose buffer is being set
Example Call
setvbuf(infile, buffer, _IOFBF, 2048);
Returns
If successful, setubuf returns a zero. In case of bad parameters or
other errors, the return value will be a nonzero.
See Also
setbuf
setvbuf
94 ANSI C Files and 1/0
Example
Line 66 in Example 7-2 turns off buffering when performing bi-
nary read and write operations on a file.
> sprintf
Purpose >
Use the sprintf function to format and write the values of vari-
ables to the string given in p__string. See printf for a description
of format _string.
Syntax
#include <stdio.h>
int sprintf(char *p_string, const char *format_string,...);
char *p_string; Pointer to an array of characters to which sprintf
sends its formatted output
Example Call
sprintf(buffer, "FY 88 Profit = %.2f\n", profit);
Returns
See Also
Example
Line 50 in Example 7-1 uses sprintf to insert a line number into a
line read from a file.
NS SS SS SS
m sscanf
Purpose
Use sscanf to read characters from buffer and convert and store
them in variables according to the formats specified in for-
mat _string. See scanf for a description of the format_string
argument.
sscanf
7—ANSI C File 1/0 Routines 95
Syntax
#include <stdio.h>
int sscanf(const char *buffer, const char *format_string,...);
const char *buffer; Pointer to buffer from which characters will be
read and converted to values of variables
Example Call
sscanf(buffer, "Name: %s Age: %d'', &name, &age);
Returns
The sscanf function returns the number of fields that were suc-
cessfully read, converted, and assigned to variables. The count
excludes items that were read and ignored. If the string ends be-
fore the read operation is completed, the return value is the con-
stant EOF.
See Also
fscanf, scanf
tmpfile <
Purpose
Use tmpfile to open a temporary file for binary read/write opera-
tions (wb+ mode). The file is automatically deleted when your
program terminates normally or when you close the file.
Syntax
#include <stdio.h>
FILE *tmpfile(void);
Example Call
p_tfile = tmpfileQ;
Returns
See Also
fclose, tmpnam
tmpfile
96 ANSI C Files and I/0
5se
> tmpnam
Purpose
Use the tmpnam function to generate a temporary file name in
the string file__name, which must have enough room to hold at
least L__tmpnam (a constant defined in stdio.h) characters. You
can generate_up to TMP_MAX (another constant defined in
stdio.h) file names with tmpnam.
Syntax
#include <stdio.h>
char *tmpnam(char *file_name);
char *file_name; Pointer to string where file name will be returned
Example Call
tmpnam(t filename) ;
Returns
See Also
tmpfile
> ungetc
PURPOSE
Use ungetc to push the character c back to stream. The charac-
ters that are pushed back are returned to subsequent read opera-
tions On stream in reverse order. You can push any character
except the constant EOF. Since wngetc pushes the character into
the stream’s buffer, any operation that tampers with the buffer or
the file’s current position (for example,fseek, fsetpos, or rewind)
may discard the pushed-back characters.
Syntax
Hinclude <stdio.h>
jnt ungetc(int c, FILE *stream);
int ¢y Character to be pushed into the file’s buffer
ungetc
7—ANSI C File |/0 Routines 97
Example Call
ungetc(last_char, infile);
Returns
See Also
fgetc, fputc, getc, getchar, putc, putchar
viprintf <
Purpose
Use ufprintf to write formatted output to stream, just as fprinif
would, except that vfprintf accepts a pointer to the list of vari-
ables (in arg__pointer) rather than the variables themselves, al-
lowing a variable number of items to be printed. See printf fora
detailed description of the format_ string argument.
Syntax
#include <stdarg.h>
#include <stdio.h>
Example Call
vfprintf(stderr, p_format, p_arg);
Returns
The vufprintf function returns the number of characters it has
printed, excluding the terminating null character.
See Also
printf, sprintf, vprintf, vsprintf, va_arg, va_end
Example
See Example 7-3 at the end of this chapter. Line 29 in that ex-
ample uses vfprintftoimplement an error-handling routine that
accepts a variable number of arguments.
viprintf
98 ANSI C Files and 1/0
_______
ee
> voprintf
Purpose
Use uvprintf to perform the same functions as printf (that is, write
formatted output to stdout) when you only have a pointer to the
list of variables to be printed (in arg_pointer) rather than the
variables themselves. This allows a variable number of argu-
ments to be printed. The format_string is described under
printf.
Syntax
#include <stdarg.h>
#include <stdio.h>
Example Call
vprintf(p_format, p_arg);
Returns
See Also
fprintf, printf, sprintf, vfprintf, va_arg, va_end
Example
Line 29 in Example 7-3 uses ufprintf. You can use vprinif in a
similar manner.
> vsprintf
Purpose
Use usprintf to perform the same function as sprintf (i.e., write
formatted output to the string p__string) except that vsprintf
vsprintf
7—ANSI C File 1/0 Routines 99
Syntax
#include <stdarg.h>
#include <stdio.h>
Example Call
vsprintf(err_msg, p_format, p_arg);
Returns
See Also
Example
Line 29 in Example 7-3 uses vfprintf. You can use vsprintfin a
similar manner.
vsprintf
100 ANSI C Files and 1/0
NS a a ea a */
2:/* A simple data storage and retrieval program */
Bie
4:#include <stdio.h>
5:#include <stdlib.h>
6:#include <string.h>
v:
8:/* Define data structures */
9:struct file_header
10:¢
Tas unsigned recordsize;
nliZis unsigned numrecords;
oa
14:
15:struct book_record
nose
ies char titlel80];
18: char author_last(20];
We char author_first[20];
20: char publisher[40];
Zi unsigned year;
eal?
25%
24:/* Declare data objects */
25:static struct book_record mybooks[] =
26:f
ts {"Microsoft C Bible", ''Barkakati", "Naba'',
28: "Howard Sams & Company", 1988},
102 ANSI C Files and 1/0
81: 2
82:
83:/* Let user manipulate data base */
84: printf("Enter command\n(f = find a record, "
85: "q = quit):");
86:/* Command processing loop */
87: while( (c = getchar()) != EOF)
88: {
89:/* Flush buffer so that fresh input can be read */
90: fflush(stdin);
91: switch (c)
92: {
93: case 'f': /* FIND */
94: case 'F';
95: printf("Book's title: '");
96: gets(bktitle);
97: s_len = strlen(bktitle);
98:/* Advance file pointer past file header */
99: fseek(dbfile, (long)sizeof (struct
100: file_header), SEEK_SET);
101:/* Find data record with this title */
102: do
103: {
104: fpos = ftell(dbfile);
105: numread = fread(&book, sizeof (struct
106: book_record), 1, dbfile);
107: len = strlen(book.title);
108: /* Compute length to compare */
109: len = min(s_len, len);
110: 3
Ae while(numread == 1 &&
112: strncmp(book.title, bktitle, len) != 0);
113: if (numread != 1) ;
114: {
115:/* Book by this author is not in data base */
116: fprintf(stderr, '"%s not in"
117: "data base\n", bktitle);
118: exit(3);
ARO D:
120:/* Display the
record that was found */
raul printf('\n---- FOUND ----\n''
122: ue Title: %s\n"
123: "Author: %s %s\n"
124: "Publisher: %s\n'"'
1252 dt Year: Zu\n'"', book.title,
126: book.author_first, book.author_last,
2G: book.publisher, book.year);
128:/* We have the spot marked for this record. If this
129: * record were updated, you could go to this position
130: * with fseek(dbfile, fpos, SEEK_SET) and use fwrite
131: * to write back the updated record.
ASeee kL.
104 ANSI C Files and !/0
133: break;
134:
135: case ‘q': /* QUIT */
136: case ‘Q':
“IBI/2 printf("\nExiting...\n'");
138: fclose(dbfile); /* Close file */
139: exit(0); :
140: } 141:/* Ask user for command again */
142: printf('\nEnter command\n(f = find a record, "'
143: ~ Ng = quite)
144: }
1453}
1:#include <stdio.h>
2:#include <stdarg.h>
3:void error_handler(char *,...);
4:char filename[80] = ''EXAMPLE.C'':
5:main()
6:¢
G int line_no = 31;
8:/* Call the error handler to print an error message.
9: * First just a single line. Then a more detailed message
10: * with more arguments.
Toe,
nee error_handler(''Syntax error\n');
ENP error_handler("'File: %s at line: %d\n'"', filename,
14: line_no);
1533
NOS] Rr crn errno */
17:/* error_handler: accepts variable number of arguments
18: * and prints messages to stderr
192 -#/
20:void error_handler(char *my_format,...)
PANERS
Zes va_list arg_pointer;
23:/* Use va_start macro to get to the start of the variable
24: * number of arguments. This will alter the pointer
25: * arg_pointer to point to the list of variables to be
26: * printed.
Ce
28: va_start(arg_ pointer, my_format);
29s vfprintf(stderr, my_format, arg_pointer);
7—ANSI C File |/0 Routines 105
ss)
> =~
0 ae ike
*
rieie
Be a
ANSI C Process Control and
Memory Management
107
Process Control
Introduction
The process control routines include the signal-handling rou-
tines that take care of error conditions, and the utility routines
that terminate a process, communicate with the operating sys-
tem, and set up numeric and currency formats. The routines de-
scribed in this chapter are defined in locale.h, signal.h, setjmp.
h, and stdlib.h.
Signals
Signals are the operating system’s way of interrupting a process
when certain error conditions, also called “exceptions,” occur.
109
110 ANSI C Process Control and Memory Management
main()
{
if (setjmp(saved_context) == 0)
{
do_something();
3:
else
{
/* This part executed when longjmp is called «*/
handle_error();
}
}
do_something()
at
int something_wrong;
Locale of a Program
The term “locale” refers to the locality (a country) for which cer-
tain aspects of your program can be customized. ANSI C groups
the country or locale-dependent aspects of a C program into six
categories. Table 8-2 summarizes the locale categories defined in
the header file Jocale.b. You can use the setlocale function to set
each category shown in Table 8-2 to conform to a selected locale.
The locale named “‘C”’ indicates the minimal environment for C
translation. Other locale names will be implementation depen-
dent. The locale-specific functions and formatting information
are not yet present in any commercial C compilers. However, as
compilers begin to provide full ANSI compatibility, these func-
tions should become available in most C compilers.
112 ANSI C Process Control and Memory Management
Terminating a Process
You can use two functions to terminate a process: abort and exit.
Of course, any process terminates automatically when its body
of code ends. When a C process terminates normally via a call to
exit or when its execution is complete, several things happen.
First, a set of up to 32 routines that were installed earlier by calls
to atexit are called in a last-in first-out (LIFO) order. Then, all
buffers associated with streams open for I/O will be flushed. Fi-
nally, the process will end and control will return to its parent.
The abort function terminates a process without going
8—Process Control 113
Routine Description
abort Raises the SIGABRT signal after printing a message to stderr. The
normal handler for SIGABRT terminates the process without flushing
file buffers.
assert Prints a diagnostic message and aborts program if a given logical
expression is false.
atexit Installs a routine to a stack of at least 32 routines that will be called in
“Jast-in first-out” order when the process terminates.
exit Calls the functions installed by atexit, flushes all buffers associated
with streams that are open for 1/0, and terminates the process and
returns to the operating system.
getenv Returns the definition of an environment variable from the environment
of the process.
localeconv Sets the components of a /conv structure with information about
numeric and monetary formatting appropriate for the current locale.
longjmp Restores the context of a process, which causes an unconditional
jump to the place from which setimp was called to save that
particular context.
perror Prints an error message using your message and the system message
corresponding to the value in the global variable errno.
raise Generates a signal (an exception).
setimo Saves the context of a process in a buffer that can be used by /ongjmp
to jump back.
signal Installs a function to handle a specific exception or signal.
setlocale Selects a locale for a specified portion of the program’s locale-
dependent aspects.
system Executes an operating system command.
Task Routines
E
(PRE SEE a S
> abort
Purpose
Use abort, which calls raise(SIGABRT), to exit your program ab-
normally. Note that unlike exit, abort will not flush the file buf-
fers or call the routines set up by atexit. You can take care of
these chores; however, by setting up the processing for the
SIGABRT signal.
Syntax
#include <stdlib.h>
void abort(void);
Example Call
abort ();
See Also
> assert
Purpose
Use the assert macro to print an error message and abort the pro-
gram if the <expression) is false. Typically, assert is used to iden-
tify program errors during the debugging phase. After the
program is debugged, you can disable all occurrences of the as-
sert macros by defining the preprocessor macro NDEBUG.
Syntax
#include <assert.h>
void assert (<expression>);
<expression> C statements specifying assertion being tested
Example Call
assert(arg_ value >= 0);
See Also
abort
assert
8—Process Control 115
SSS)
atexit <4
Purpose
Use atexit to set up a stack of up to 32 (this is the minimum num-
ber specified by ANSI C) functions that the system will call in
LIFO order when your program terminates normally. Note that
the functions passed to atexit cannot take arguments. This fea-
ture is useful for setting up housecleaning chores to be per-
formed at program termination.
Syntax
#include <stdlib.h>
int atexit(void (*func) (void));
void (*func) (void); Pointer to function to be called
Example Call
atexit(cleanup_all);
Returns
See Also
exit
Example
See Example 8-1 at the end of the chapter. Line 18 in that example
installs the cleanup function that will be called when the pro-
gram exits by an exit call.
exit <4
Purpose
Use exit to terminate your program normally by flushing file
buffers, closing files, and invoking functions set up with alexit.
A value of zero or EXIT __SUCCESS for status means normal exit.
EXIT_FAILURE indicates errors.
Syntax
H#include <stdlib.h>
void exit(int status);
int status; Exit status code
exit
116 ANSI C Process Control and Memory Management
Example Call
exit (EXIT_SUCCESS);
See Also
abort, atexit
Example
Lines 23, 51,-60, and 71 in Example 8-1 show calls to exit.
LS SD
> getenv
Purpose
Use getenv to get the definition of the environment variable
varname from the environment of the process.
Syntax
#include <stdlib.h>
char *getenv(const char *varname);
const char *varname; Name of environment variable to look for
Example Call
current_path = getenv("PATH') ;
Returns
> localeconv
Purpose
Use the localeconv function to get detailed information on for-
matting monetary and numeric values by the rules of the current
locale,
Syntax
#include <locale.h>
struct lconv *localeconv(void);
Example Call
p_lconv = localeconv();
localeconv
8—Process Control 117
Returns
in nonmonetary quantities */
char *int_curr_symbol; /* International currency symbol
for the current locale */
char *currency_symbol; /* Local currency symbol
for the current locale */
char *xmon_decimal_point; Decimal point character for
monetary quantities */
char *mon_thousands_sep; Separator for groups of digits
to the left of decimal point
for monetary quantities */
char *mon_grouping; /* Size of each group of digits
in monetary quantities */
char *positive_sign; /* String denoting sign for non-
negative monetary quantities
*/
char *xnegative_sign; /*x String denoting sign for
negative monetary quantities
*/
char int_frac_digits; /* Number of digits to the right
of decimal point in
internationally formatted
monetary quantities */
char frac_digits; /* Number of digits to the right
of decimal point in formatted
monetary quantities */
char p_cs_precedes; |x 1 = currency_symbol precedes,
0 = succeeds positive value */
char p_sep_by_space; /* 1 = space, 0 = no space
between currency_symbol and
positive formatted values */
char n_cs_precedes; /* 1 = currency_symbol precedes,
0 = succeeds negative value */
char n_sep_by_space; /* 4 space, 0 = no space
between currency_symbol and
negative formatted values */
char p_sign_posn; /* Position of positive_sign
in positive monetary
quantities */
localeconv
118 ANSI C Process Control and Memory Management
See Also
setlocale
> longimp
Purpose
Use the /ongjmp function to restore the calling environment to
that contained in the jmp_buf array env. This environment
must have been saved by an earlier call to setjmp. Note that
longjmp restores all local variables (except the ones declared
volatile) to their previous states and returns as if from the last call
to setijmp with the return value retval.
Since /ongjmp jumps to the return address of the last match-
ing call to setjmp, make sure that the call to Jongjmp occurs be-
fore the function in which you called setjmp has returned.
Syntax
‘Hinclude <set jmp.h>
void longjmp(jmp_buf env, int retval);
jmp_buf env; Array data type where the calling environment is stored
Example Call
longjmp(stack_env, 1);
See Also
set jmp
Example
Line 75 in Example 8-1 calls /ongjmp to return to the main com-
mand loop when the user presses a Control-C.
SE
EE
Pm perror
Purpose
Use perror to construct an error message concatenating the mes-
perror
8—Process Control 119
sage you provided in the argument string with the system mes-
Sage corresponding to the current value in the global variable
errno and print the message to stderr.
Syntax
#include <stdio.h>
void perror(const char *string);
const char *string; Your part of the message
Example Call
perror("Error closing file");
See Also
strerror
Example
Line 22 in Example 8-1 uses perror to display an error message.
raise <4
Purpose
Use rdise to “raise a signal” that creates an exception condition
corresponding to the number signum. The exception is handled
by invoking a routine set up earlier by calling the function sig-
nal. The abort function uses raise to create the exception
SIGABRT to initiate actions to be taken when aborting a pro-
gram.
Syntax
#include <signal.h>
int raise(int signum);
int signum; Signal number to be raised
Example Call
raise(SIGABRT) ;
Returns
If successful, raise returns a zero. Otherwise, it returns a non-
zero value.
See Also
abort, signal
raise
120 ANSI C Process Control and Memory Management
> setjmp
Purpose
Use the setjmp macro to save a stack environment in the
jmp —buf array env before calling another function. You can re-
store this environment by a call to /ongjmp, achieving the effect
of a nonlocal goto. When /ongjmp is called later with the saved
calling environment, it restores all stack-based local variables in
the routine to the values they had when setjmp was called and
then jumps to the return address that setjmp saved. This feels
like a return, one more time, from the last call to setjmp. Note
that this process does not guarantee the proper restoration of
register-based and volatile variables.
Syntax
#include <setjmp.h>
int setjmp(jmp_buf env);
jmp_buf env; Array data type where the current calling environment is
stored
Example Call
if (setjmpCenv) != 0) printf ("Returned from longjmp\n");
Returns
After saving the stack environment, setjmp returns a zero. When
longjmp is called with the environment saved by this call to
setjmp, the effect is of returning from setjmp again, this time
with the second argument of /Jongjmp as the return value.
See Also
Long jmp
Example
Line 30 in Example 8-1 establishes a mark in the main program to
which you can jump from any place in the program by calling
longjmp.
SSS
> setlocale
Purpose
Use setlocale to define the locale named in the string /o-
cale__name for the locale-dependent aspects of your program
setlocale
8—Process Control! 121
Syntax
#include <locale.h>
char *setlocale(int category, const char *locale_name);
int category; Indicates which part of your program’s locale-dependent
aspects you are defining a locale for: LC_ALL,
LC_COLLATE, LC_CTYPE, LC __MONETARY,
LC_NUMERIC, or LC_TIME
char *locale_name; The name of the locale that will control the
Specified category
Example Call
setlocale(LC_ALL, ''C");
Returns
See Also
localeconv
signal <
Purpose
Use the signal function to set up the routine func as the handler
for the exception or signal number signum. The handler is ex-
pected to accept the signal number as an argument. The signal
number signum must be one of the constants shown in Table
8-1. These are defined in the include file signal. h. If you want to
ignore a signal, use SIG__IGN as the second argument to s7gnal.
Specifying SIG__DFL as the second argument sets up the imple-
mentation-defined default handling for the signal.
Syntax
#include <signal.h>
void (*signal(int signum, void (*func) Cint))) Cint);
int signum; Signal number for which a handler is being set up
Example Call
if(signal (SIGINT, ctrlc_handler) == SIG_ERR)
signal
122 ANSI C Process Control and Memory Management
{
perror("signal failed");
exit (0);
a6
Returns
If successful, signal returns the pointer to the previous handler.
In case of error, it returns the constant SIG_ERR and sets the
global variable errno to an implementation-defined error con-
stant. SS
See Also
abort, raise
Example
Lines 20, 68, and 73 in Example 8-1 illustrate the use ofsignal to
handle the SIGINT signal.
> system
Purpose
Use system to execute the operating system command contained
in string from your program. If string is NULL, system returns a
nonzero value only if a command processor (for example, the
UNIX shell) is present in the environment.
Syntax
#include <stdlib.h>
int system(const char *string);
const char *string; Command to be executed
Example Call
system("Ls'"');
Returns
; system
8—Process Control 123
Example 8-1 The pair setjmp and longjmp is ideal for error
handling or handling special conditions ina
program. You call setjmp at a place where vou
have code that you may want to execute later.
Then, whenever your conditions are met, call
longjmp with the jmp_ buf variable saved ear-
lier by setjmp. This places you where setjmp
was called originally. It appears as if the setjmp
function returned a second time, this time
with the value from the second argument to
longjmp. Here is a small program that illus-
trates a way to use this versatile duo. Notice
how atexit is used to set up a function that
handles housecleaning chores before exiting
the program. This program also establishes
signal handling for the Control-C keypress
(SIGINT signal).
1:#include <stdio.h>
2:#include <signal.h>
3:#include <setjmp.h>
4:
5:static int ctrlc_handler(int);
6:static void cleanup(void);
as
8:/* Buffer used by setjmp and longjmp */
9:jmp_buf main_menu;
10:
11:static FILE *datafile = NULL;
12:
13:main®
T4Et
iD char input(80];
16: int choice=0;
17:/* Install routine to be called by ‘exit’ */
18: atexit (cleanup);
19:/* Take over the Control-C interrupt */
20: if(signal (SIGINT, ctrlc_handler) == SIG_ERR)
21: xg
22: perror("signal failed’);
233 exit(1);
24: }
2a printf("Installed SIGINT signal handler\n"');
26:
27:/* Call ‘setjmp’ to set up for returning to this
28: * point after user presses Control-C
29: */
30: if(setjmp(main_menu) != 0)
571: {
32:/* Returning from a ‘longjmp' -- print message */
53% printf (''Interrupted...\n');
34: fflush(stdin); /* flush input buffer */
35: }
124 ANSI C Process Control and Memory Management
Introduction
In writing C programs you encounter functions, such as printf,
that can take a variable number of arguments. Take, for instance,
a routine (findmax) that picks the largest integer from an array. If
the routine can accept a variable number of arguments, you can
use such calls as findmax(1,2,3) and findmax(a,b,c,d) to find
the maximum of any number of arguments. A set of macros in
ANSI C makes handling a variable number of arguments a
straightforward task.
125
126 ANSI C Process Control and Memory Management
Macro Description
Purpose
S yntax
# include <stdarg.h>
< type> va_arg(va_list arg_ptr, <type>);
void va_end(va_list arg_ptr);
Vv oid va_start(va_list arg ptr, prev_param);
Example Call
v a_start(argp, firstint);
f
irst_x = firstint;
n ext_x = va_arg(argp, int);
Returns
See Also
Introduction
Most computer systems store instructions and data in memory
and use a central processing unit (CPU) such as the Intel
8088/8086 microprocessor in an IBM PC or the Motorola
MC68000 in an Apple Macintosh to retrieve instructions from
memory and execute them. The operating system, itself a pro-
gram residing in memory, takes care of loading other programs
and executing them. It has its own scheme of managing the avail-
able memory for its data and that for other programs as well.
In older programming languages, such as FORTRAN, no
provision is made for requesting memory at run-time. All data
items and arrays have to be declared before the program is com-
piled, so you have to guess beforehand the maximum size of an
array and there is no way to exceed the maximum other than by
recompiling the program. This is inefficient because you are
locking in the maximum amount of memory your program will
ever need.
In most modern languages, including C, you can request
blocks of memory at run-time and release the blocks when your
program no longer needs them. A major advantage of this is that
you can design your application to exploit all available memory
in the system. Like most other capabilities in C, this one is avail-
able as a set of library routines, known as the “memory alloca-
tion” routines. The ANSI C set has four basic memory allocation
routines.
129
130 ANSI C Process Control and Memory Management
Routine Description
calloc Allocates memory for an array of data elements and nitializes them to zero
free Frees previously allocated memory
malloc Allocates a number of bytes and returns a pointer to the first byte of the
allocated memory
realloc Enlarges or shrinks a previously allocated block of memory, moving the
block in the physical memory of the system, if necessary
Requesting Memory
You can use either malloc or calloc to get the needed memory.
While malloc simply returns a block of memory of specified
size, calloc allocates room for an array of a specified number of
elements, each of a given size, and it also initializes all the allo-
cated bytes to zero. Use the sizeof operator to get the size of a
data element.
must always check for a NULL return value when you call any
memory allocation routines.
Releasing Memory
If you no longer need the data you stored in a block of memory
and you do not plan to store anything in that memory, you
should call free to release the block. Always pass a valid pointer
to the free function; if you pass a pointer that was not returned
by the calloc, malloc, or realloc, later calls to the memory alloca-
tion functions may fail.
Further Reading
Memory management is covered in most books on operating
systems. The books on XINU by Comer' and on MINIX by Ta-
nenbaum? describe memory management from the point of
view of an operating system. Each book includes samples of C
code that implement the memory management algorithms.
Knuth’s classic text? describes the basic algorithms used in de-
ciding how to assign a particular block of memory to satisfy a
request. For a more practical and relevant description of the C
memory allocation routines and their usage, consult Prata’s
book".
1. Douglas Comer, Operating System Design: The XINU Ap-
proach, Prentice-Hall, Inc., Englewood Cliffs, NJ, 1984, 486
pages.
2. Andrew S. Tanenbaum, Operating Systems Design and Im-
plementation, Prentice-Hall, Inc., Englewood Cliffs, NJ.
1987, 719 pages.
3. Donald E. Knuth, The Art of Computer Programming, Vol-
ume 1: Fundamental Algorithms, Addison-Wesley, Read-
ing, MA, 1968, 640 pages.
4. Stephen Prata, The Waite Group’s Advanced C Primer++.
Howard W. Sams & Company, Indianapolis, IN, 1986, 502
pages.
132 ANSI C Process Control and Memory Management
ss
> calloc
Purpose
Use calloc to allocate memory for an array af num_elems ele-
ments, each of size elem__size bytes. All bytes of the allocated
array will be initialized to zero.
Syntax
#include <stdlib.h>
void *calloc(size_t num_elems, size_t elem_size);
size_t num_elems; Number of elements
Example Call
p_int = (int *) calloc(100, sizeofCint));
Returns
See Also
free, malloc, realloc
Example
See Example 10-1 at the end of the chapter. Line 9 in that example
uses calloc to allocate a buffer.
> free
Purpose
Use the free function to deallocate (return to the pool of free
memory) a block of memory allocated earlier by malloc, calloc,
or realloc. The address of the block is specified by the argument
mem _dddress, which is a pointer to the starting byte of the
block. A NULL pointer argument is ignored byfree.
Syntax
#include <stdlib.h>
void free(void *mem_address);
void *mem_address; Pointer to block of memory to be released
free
10—Memory Allocation 133
Example Call
free(buffer);
See Also
Example
Lines 38 and 39 in Example 10-1 use free to deallocate memory.
Purpose
Syntax
#include <stdlib.h>
void *malloc(size_t num_bytes);
size_t num_bytes; Number of bytes needed
Example Call
buffer = (char *)malloc(100*sizeof(char));
Returns
See Also
free, calloc, realloc
Example
Line 20 in Example 10-1 uses malloc to allocate room for a buffer.
realloc <4
Purpose
Use the realloc function to change the size of an allocated block
of memory to a new Size given in the argument newsize. The ad-
dress of the block is specified by the pointer mem _address.
realloc
134 ANSI C Process Control and Memory Management
Syntax
#include <stdlib.h>
void *realloc(void *mem_address, size_t newsize);
void *mem_address; Pointer to the block of memory whose size is to be
altered
Example Call
new_buffer = realloc(old_buffer, old_size+100);
Returns
See Also
Example
Line 30 in Example 10-1 uses realloc to enlarge the size of an allo-
cated buffer.
Example 10-1 Illustrate the use of the memory allocation
routines by allocating two buffers, one with
calloc and the other by malloc. Enlarge one of
the buffers by calling realloc. Free the buffers
using free.
#include <stdio.h>
#include <stdlib.h>
main®
{
char *buffer1, *buffere;
— se
of
ef
#8
es /* Allocate room for string and check for NULL */
CONOouUrWN
oe
realloc
10—Memory Allocation 135
v4
iy i
IV
ANSI C Data Processing
RY)
17
Data Conversion
Introduction
Using computers for information management frequently re-
quires crunching numbers. These numbers are represented in
several forms internally, depending on the type of C variable in
which the value is held. The ANSI C data conversion routines,
declared in the header file stdlib.h, allow conversion back and
forth between the internal form of a C variable and the character
string representations to be read.
139
140 ANSI C Data Processing
Character String
oV/100 00007,
7.01014 1001_|
IEEE format
100.0 as
double Mantissa
Address of
double
ae bie —. variable
Routine Description
value1 = atof(argv[1]);
value2 = atof(argv[3]);
switch(argv([2][0])
xf
}
printf("%f", result);
Task Routines
> atof
Purpose
Use the atof function to convert the argument string into a
double value. A call to atof is equivalent to the call strtod(string,
(char * *)NULL).
Syntax
#include <stdlib.h>
double atof(const char *string);
const char *string; Stringto be converted
Example Call
dbl_value = atof(input_string);
Returns
See Also
atof
11—Data Conversion 143
atoi <<
Purpose
Use the ato# function to convert the argument string into an int
value. A call to atoz is equivalent to the call (int)strtol(string.
(char **)NULL, 10).
Syntax
#include <stdlib.h>
int atoi(const char *string);
const char *string; String to be converted
Example Call
int_value = atoi(input_string);
Returns
The atoi function returns the integer value as an int variable.
See Also
atol <4
Purpose
Use the ato/ function to convert the argument string into a long
integer value. A call to @tol is equivalent to the call strtol(string.
(char **)NULL, 10).
Syntax
#include <stdlib.h>
int atol(const char *string);
const char *string; String to be converted
Example Call
long_value = atol(input_string);
Returns
See Also
atol
144 ANSI C Data Processing
> strtod
Purpose
Use the strtod function to convert string to a double-precision
value. The string is expected to be of the form
[whitespace][sign][digits. digits]
[exponent _letter][sign][digits]
where whitespace refers to (optional) blanks and tab characters,
sign isa + ora-, and the digits are decimal digits. The exponent__
letter can be any one of d, D, e, or E(no matter which exponent
letter is used, the exponent always denotes a power of 10). If
there is a decimal point without any preceding digit, at least one
digit must follow it. The strtod function begins the conversion
process with the first character of string and continues until it
finds a character that does not fit the above form. Then it sets
endptr to point to the leftover string, provided endpir is not
equal to NULL.
Syntax
#include <stdlib.h>
double strtod(const char *string, char **endptr);
const char *string; Pointer to character array from which double-
precision value will be extracted
.
Example Call
dbl_value = strtod(input_string, &endptr);
Returns
See Also
strtod
11—Data Conversion 145
strtol <
Purpose
Use the strtol function to convert string to a long integer value.
The string is expected to be of the form
[whitespace][sign][O][x or X][digits]
where whitespace refers to (optional) blanks and tab characters,
sign is a + Or a-—, and the digits are decimal digits. The string is
expected to contain a representation of the long integer using
the argument radix as the base of the number system. However,
if radix is given as zero, strtol uses the first character in string to
determine the radix of the value. Here are the rules:
Other radixes may be specified via the argument radix. The let-
ters a through z (or A through Z) are assigned values 10 through
35. For a specified radix, strto/l expects only those letters whose
assigned values are less than the radix.
The sirtol function begins the conversion process with the
first character of string and continues until it finds a character
that meets the above requirements. Before returning, strfol sets
endptr to point to that character, provided it is nota null pointer.
Syntax
#include <stdlib.h>
long strtol(const char *string, char **endptr, int radix);
const char *string; Pointer to character array from which the long
integer value will be extracted
int radix; Radix in which the value is expressed in the string (radix
must be between 2 and 36)
Example Call
value = strtol(input, &endptr, radix);
strtol
146 ANSI! C Data Processing
Returns
The strto/ function returns the long integer value except when it
would cause an overflow. In case of overflow, strtol sets errno to
ERANGE and returns either LONG__MIN or LONG_ MAX, de-
pending on whether the value was negative or positive, respec-
tively.
See Also
atol, strtoul
> strtoul
Purpose
Use strtoul to convert a character string to an unsigned long inte-
ger.
Syntax
#Hinclude <stdlib.h>
unsigned long strtoul(const char *xstring, char **endptr,
int radix);
int radix; Radix in which the value is expressed in the string (radix
must be between 2 and 36)
Example Call
value = strtoul(input_string, &stop_at, radix);
Returns
The strtoul function returns the unsigned long integer value ex-
cept when it would cause an overflow. In case of overflow, strtoul
sets errno to ERANGE and returns the value ULONG_
MAX.
See Also
atol, strtol
Example
Example 11-1 shows a hexadecimal calculator program that uses
strtoul to read hexadecimal values from the command-line argu-
ments (lines 14 and 15).
strtoul
11—Data Conversion 147
a
y
—— “
:
es + 3 ih j ‘apne toni no
> a
A u = EM og @
~.
i ma co)! Ne‘a; sere <
= pe Chee 3) a
, : ’ , — “ OMS
has alt xeds ae Triaiay- i 7
ee RAT ~~ SeRey
; : ae. oe
*% " eS 7
Introduction
In addition to the support for basic floating-point operations in
the language, the ANSI C library includes a set of math functions
to perform such common mathematical operations as the sine
and the cosine.
Floating-Point Operations
Floating-point variables hold floating-point numbers, which are
numbers with fractional parts. When you write such numbers,
there is usually a decimal point somewhere, for example, 1.2345
x 10°. This notation of writing floating-point numbers is known
as scientific or engineering notation. In fact, any floating-point
number can be represented in this form: a “mantissa” (the num-
ber’s significant digits) multiplied by 10 raised to the power of an
integer “exponent.” The mantissa and exponent form is how
floating-point numbers are represented in ANSI C, except that
instead of the exponent representing a power of 10, it represents
a power of 2, since base 2 is a computer’s natural format.
149
150 ANSI C Data Processing
Sign bit Biased eee Implicit 1 53- y mantissa (last bit implicit)
63 52 51 F 0
double precision or “long real”
Biased 24-bit mantissa
Sign bit exponent Implicit 1 (last bit not stored)
4
float
4 bytes
31 23 22 0
single precision or “short real”
1.01011 x 27
The IEEE format for floating-point storage uses a sign bit, a man-
tissa, and an exponent representing the power of two. The sign
bit denotes the sign of the number: a 0 represents a positive
number and a 1 denotes a negative value. The mantissa is repre-
sented in binary. Constraining the floating-point number to be in
normalized form results in a mantissa whose most significant bi-
nary digit is always 1. The IEEE format takes advantage of this by
12—Math Functions 151
Routine Description
Integer Arithmetic
Four routines use integer arguments to handle arithmetic. The
abs and labs routines return the absolute value of an integer and
a long integer, respectively. The div function divides one integer
by another and returns the integer quotient and an integer re-
mainder. The /div function operates similarly, but with long inte-
ger arguments.
Evaluate trigonometric functions acos, asin, atan, atan2, cos, sin, tan
Evaluate powers and logarithms exp, frexp, Idexp, log, log10, pow
Compute square root sqrt
Compute magnitudes and absolute values abs, fabs
Find integer limits (lower and upper) for ceil, floor
floating-point numbers
Evaluate hyperbolic functions cosh, sinh, tanh
Break down floating-point number into modf
integer and fraction
Find floating-point remainder fmod
Perform integer arithmetic abs, div, labs, Idiv
Generate random numbers rand, srand
Further Reading
If you need to use the trigonometric functions often, you will
find the handbook by Abramowitz and Stegun! a good reference
for these and many other mathematical functions. The IEEE
standard for binary floating-point arithmetic is described in a
reference booklet’ that can be obtained from Global Engineer-
“ing Documents, 2805 McGaw Ave., Irvine, CA 92174.
1. Milton Abramowitz and Irene A. Stegun, Editors, Handbook
of Mathematical Functions with Formulas, Graphs and
Mathematical Tables, Dover Publications, New York, NY,
1972, 1,046 pages.
2. IEEE Standard for Binary Floating-Point Arithmetic
(ANSI/IEEE Std 754-1985).
I SN Ry
> abs
Purpose
Use the abs function to get the absolute value of the integer argu-
ment 7.
Syntax
#include <stdlib.h>
int abs(int n);
int n; Integer whose absolute value is returned
abs
12—Math Functions 155
Example Call
x = abs(-5); /* x will be 5 now */
Returns
See Also
fabs, labs
Se
eae
acos <4
Purpose
Use the acos function to compute the arc cosine of an argument
x whose value lies in the range —1 to 1. The result is an angle with
value between 0 and = radians.
Syntax
#include <math.h>
double acos(double x);
double x; Argument whose arc cosine is to be computed
Example Call
angle = acos(0.5); /* angle is "pi''/3 */
Returns
See Also
cos
asin <4
Purpose
Use the asin function to compute the arc sine of the argument x
provided its value lies in the range —1 to 1. The result is an angle
with a value between —7/2 and 7/2 radians.
Syntax
#include <math.h>
double asin(double x);
double x; Argument whose arc sine is to be computed
asin
156 ANSI C Data Processing
Example Call
angle = asin(0.707) /* angle is roughly "pi''/4 */
Returns
See Also ~-
sin
> atan
Purpose
Use the atan function to compute the arc tangent of the argu-
ment x. The result is an angle with a value between —7/2 and /2
radians.
Syntax
#include <math.h>
double atan(double x);
“double x; Argument whose arc tangent is to be computed
Example Call
angle = atan(1.0) /* angle is "pi''/4 */
Returns
The atan function returns the angle in the range —7/2 and 2/2
whose tangent is equal to x.
See Also
atan2, tan
> atan2
Purpose
Use the atan2 function to compute the arc tangent of the ratio of
the arguments y/x. The result will be an angle with value be-
tween —7 and @ radians. In contrast to atan which takes a single
atan2
12—Math Functions 157
argument, atan2 can use the sign of the two arguments to deter-
mine the quadrant (a quadrant is a 90° sector in Cartesian coor-
dinates) in which the angle should lie.
Syntax
#include <math.h>
double atan2(double y, double x);
double x, y; Arc tangent of y/x will be computed
Example Call
angle = atan2(y, x);
Returns
See Also
atan, tan
ceil <4
Purpose
Use the ced/ function to find the ceiling of a double argument x.
The “ceiling” is the smallest integral value that is equal to or just
exceeds x. This can be used in rounding a double value up to the
next integer.
Syntax
#include <math.h>
double ceil(double x);
double x; Variable whose ceiling is to be returned
Example Call
x_ceiling = ceil(4.1); /* x_ceiling is 5.0 */
Returns
See Also
floor
ceil
158 ANSI C Data Processing
> cos
Purpose
Use the cos function to compute the cosine of double argument
x
Syntax
#include <math.h>
double cos(double x);
double x; Angle in radians whose cosine is to be computed
Example Call
cos_angle = cos(ang_radian);
Returns
See Also
acos, sin
Example
‘See Example 12-1 at the end of the chapter. Line 14 in that ex-
ample computes the cosine of an angle.
> cosh
Purpose
Use cosh to compute the hyperbolic cosine of x.
Syntax
#include <math.h>
double cosh(double x);
double x; Variable whose hyperbolic cosine is to be computed
Example Call
result = cosh(x);
Returns
cosh
12—Math Functions 159
See Also
sinh
BS LE a cc ci
div <
Purpose
Use the div function to divide the first integer (numer) by the
second one (denom) and get the resulting quotient and remain-
der in a structure of type div__t. The structure of type div_t is
defined in stdlib.h as
typedef struct
x
int quot; /* The quotient */
int rem; /* The remainder */
} div_t;
Syntax
#include <stdlib.h>
div_t div(int numer, int denom);
int numer; Numerator
int denom; Denominator
Example Call
result = div(32, 5);
/* result.quot = 6 and result.rem = 2 */
Returns
See Also
ldiv
exp <4
Purpose
Use the exp function to compute the exponential of the double
variable x. The exponential of a variable x is e* where e is the
base of natural logarithm (e = 2. 7182818).
Syntax
#include <math.h>
exp
160 ANSI C Data Processing
Example Call
y = exp(x);
Returns .
See Also
log
(a ae
> fabs
Purpose
Use the fabs function to obtain the absolute value of its argu-
ment x.
Syntax
#include <math.h>
double fabs(double x);
*
Example Call
y = fabs(-5.15); /* y will be 5.15 */
Returns
See Also
abs
> floor
Purpose
Use the floor function to get the floor of a double argument x.
The “floor” is the largest integral value that is less than or equal
to x. This can be used in rounding a double down to the next
lower integer.
floor
12—Math Functions 161
Syntax
#include <math.h>
double floor(double x);
double x; Variable whose floor is to be returned
Example Call
x = floor(4.15); /* x will be 4.0 */
Returns
See Also
ceil
fmod <4
Purpose
Use the fmod function to compute the floating-point remainder
after dividing the floating-point number x by y and ensuring that
the quotient is the largest possible integral value. If this quotient
is n, then fmod returns the value r computed from the expres-
sionr=x-—n * y. The entire operation is equivalent to
double n, r;
ase'=
=) floor(x/y);
b= "x = ney
Syntax
#include <math.h>
double fmod(double x, double y);
double x, y; The remainder after the division xly is returned
Example Call
rem = fmod(24.95, 5.5); /* rem will be 2.95 */
Returns
See Also
floor
fmod
162 ANSI C Data Processing
ne
> frexp
Purpose
Use the frexp function to break down the floating-point number
x into a mantissa m whose absolute value liés between 0.5 and
1.0, and an integer exponent 7, so that x = m x 2”. The integer
exponent 7 is stored by frexp in the location given in the argu-
ment expptr.-If x is 0, the exponent will also be 0.
Syntax
#include <math.h>
double frexp(double x, int *expptr);
double x; Floating-point argument to be decomposed
Example Call
mantissa = frexp(5.1, &exponent);
/* mantissa will be 0.6375, exponent = 3 */
Returns
See Also
ldexp, modf
> labs
Purpose
Use /abs to get the absolute value of the long integer 7.
Syntax
Hinclude <stdlib.h>
long Labs(long n);
long n; Long integer whose absolute value is returned
Example Call
lresult = lLabs(-65540L); /* result will be 65540 */
Returns
labs
12—Math Functions 163
See Also
abs, fabs
a SD
Idexp <4
Purpose
Use the /dexp function to compute and obtain the floating-point
number equal to x x 2°,
Syntax
#include <math.h>
double ldexp(double x, int exp);
double x; Floating-point value of the mantissa
int exp; Integer exponent
Example Call
value = ldexp(0.6375, 3); /* value will be 5.1 */
Returns
Normally /dexp returns the value described above. When the re-
sult is too large, a range error may occur.
See Also
frexp, modf
Idiv <
Purpose
Use the /div function to divide one long integer (”~umer) by an-
other (denom) and get the resulting quotient and remainder in a
structure of type /div__t. The structure type /div_t is defined in
Sstdlib.h as
typedef struct
{
long quot; /* The quotient */
long rem; /* The remainder */
+ ldiv_t;
Syntax
#include <stdlib.h>
ldiv_t ldiv(long numer, long denom);
long numer; Numerator
Idiv
164 ANSI C Data Processing
Example Call
Lresult = ldiv(65540L, 65536L);
/* lresult.quot = 1, lresult.rem = 4 */
Returns
The /div function returns a structure of type /div_t containing
the quotient and remainder of the division.
See Also
div
Purpose
Use Jog and log /0 to compute the natural logarithm and logarithm
to the base 10, respectively, of the positive double variable x.
Syntax
#include <math.h>
double log(double x);
double log10(double x);
double x; Variable whose logarithm is to be computed
Example Call
y = log(2); /* y = 0.693147 */
a = logi0(2); /* a = 0.30103 */
Returns
For positive x, Jog and /og/0 return the logarithm ofx. Ifx is neg-
ative, a domain error occurs. If x is zero, a range error Occurs.
See Also
exp, POW
> modf
Purpose
Use the modf function to separate the floating-point number x
into its fractional part and its integral part. The integer is re-
modf
12—Math Functions 165
Syntax
#include <math.h>
double modf (double x, double *intptr);
double x; Floating-point value to be decomposed
Example Call
fraction = modf(24.95, &int_part); /* fraction is .95 */
Returns
See Also
frexp, ldexp
pow <4
Purpose
The pow function computes the value of x raised to the power y.
The arguments x and y cannot both be zero. When x is negative,
y must be an integer.
Syntax
#include <math.h>
double pow(double x, double y);
double x, y; Computes x raised to the power y
Example Call
x = pow(2.0, 3.0); /* x will be 8.0 */
Returns
See Also
pow
166 ANSI C Data Processing
___._ eee
Se
> rand
Purpose
The rand function generates a pseudorandom integer with a
value between 0 and the constant RAND__MAX defined in
stdlib.b. The seed, or starting point, of the pseudorandom inte-
gers can be set by calling srand.
Syntax
#include <stdlib.h>
int rand(void);
Example Call
random_value = randQ);
Returns
The rand function returns the pseudorandom integer it gener-
ates.
See Also
srand
Example
Line 14 in Example 12-2 shows how rand can be used to get a
random number.
> sin
Purpose
Use the sin function to compute the sine of double argument x,
which represents an angle in radians.
Syntax
#include <math.h>
double sin(double x);
double x; Angle in radians whose sine is to be computed
Example Call
y = sin(x);
Returns
sin
12—Math Functions 167
See Also
asin, cos
Example
Line 15 in Example 12-1 computes the sine of an angle.
sinh <4
Purpose
Use sinh to compute the hyperbolic sine of a double variable x.
Syntax
#include <math.h>
double sinh(double x);
double x; Variable whose hyperbolic sine is to be computed
Example Call
a = cosh(b);
Returns
See Also
cosh, tanh
sqrt <4
Purpose
Use sqrt to compute the square root of a non-negative double
variable x.
Syntax
#include <math.h>
double sqrt(double x);
double x; Variable whose square root is to be computed
Example Call
sqrt.2 = sqrt(2.0); /* sqrt_2 = 1.414 */
sqrt
168 ANSI C Data Processing
Returns
The sqrt function returns the square root of x. If x is negative, a
domain error occurs.
See Also
pow
> srand
Purpose
Use the srand function to set the seed, or starting point, of the
random number generation algorithm used by the function
rand. If seed is 1, the random number generator is initialized to
its default starting point. This generates the sequence that is pro-
duced when rand is called without a prior call to srand. Any
other value of seed sets a random starting point for the pseudo-
random sequence that is generated by rand.
Syntax
#include <stdlib.h>
void srand(unsigned seed);
unsigned seed; Starting point for random number generator
‘Example Call
srand(new_seed) ;
See Also
rand
Example
Line 11 in Example 12-2 shows how srand is used with the time
function to obtain a random starting point for a pseudorandom
sequence of numbers.
> tan
Purpose
Use the tan function to compute the tangent of an angle x whose
value is expressed in radians.
Syntax
#include <math.h>
tan
12—Math Functions 169
Example Call
y = tan(x);
Returns
See Also
Example
Line 16 in Example 12-1 computes the tangent of an angle.
tanh <
Purpose
Use tanh to compute the hyperbolic tangent of a double variable
NX
Syntax
#include <math.h>
double tanh(double x);
double x; Variable whose hyperbolic tangent is to be computed
Example Call
a = tanh(b);
Returns
See Also
cosh, sinh
tanh
170 ANSI C Data Processing
6:main()
it
8: double angle, radians, cresult, sresult, tresult;
9:
10: printf (''Angle\t\tCosine\t\tSine\t\tTan\n");
AT: for(angle = 0.0; angle <= 180.0; angle += 10.0)
12: {
13% radians = angle / R_TO_D;
14: cresult = cos(radians);
15: sresult = sin(radians);
16: tresult = tan(radians);
100s if(errno != ERANGE)
18: {
19: printf("%f deg. \tzt\t%Zt\t%f\n",
20: angle, cresult, sresult, tresult);
21: }
22: }
Osa
ied 2
> ae
ae
rene
ss ne tn.
é
—
ee
a
wee wi art:
_ stake een
sy . A, eo
a52 -_ ‘3a
= .
J31Q > : 7
oe te a
ee ae teed) on ma pe
d ae | $ Z we) a ee Shi .«“tr AAT
ana
iae. t=
a ee
“rt ri oej
‘?
{
" My
= , re jad sie “)-
Character Classification and
Conversion
Introduction
ANSI C specifies two character sets for programs: the “‘source”
character set in which programs are written, and the “execu-
tion” character set that a running program understands. The
header file ctype.b contains several functions that are useful for
classifying and converting the execution characters. The behav-
ior of these functions is affected by the LC_CTYPE category of
the current locale (see Chapter 8 for more on locales).
Function Description
173
174 ANSI C Data Processing
Function Description
> isalnum
Purpose
Syntax
#include <ctype.h>
int isalnum(int c);
inte. Character being tested
Example Call
ifCisalnum(c) != 0) printf("'%c is alphanumeric\n", c);
Returns
isalnum
13—Character Classification and Conversion 175
See Also
isalpha, isdigit
a at oa
es
Sie
isalpha <4
Purpose
Use isalpha to check if the character c is a letter. If the locale is
not C, the behavior is dependent upon the character set in use.
Syntax
#include <ctype.h>
int isalpha(int c);
int c; Character being tested
Example Call
ifCisalpha(c) != 0) printf ('%c is letter\n", c);
Returns
The tsalpha function returns a nonzero value if c is a letter. Oth-
erwise, it returns a zero.
See Also
islower, isupper
Purpose
Use this group of functions to check for specific properties of
the character c, such as whether it is a control character, a digit,
lowercase, printable, and so on. Table 13-3 shows the test per-
formed by each function.
Syntax
#include <ctype.h>
lint. 1scntrl (int c's
int isdigit(int c);
int isgraph(int c);
int islower(int c);
int isprint(int c);
int ispunct(int c);
int isspace(int c);
int isupper(int c);
int isxdigit(int c);
int ¢} Character to be tested
Example Call
ifCisprint(c) != 0) printf(''%c is printable\n", c);
if(isdigit(c) != 0) printf ("%ec is a digit\n", c);
ifCisentrl(c) != 0) printf("%d is a control char\n", c);
Returns
Each function returns a nonzero value if c satisfies the criterion
for that function. Otherwise it returns a zero.
See Also
isalnum, isalpha
> tolower
Purpose
Use the tolower function to convert the uppercase letter C to
lowercase.
Syntax
#include <ctype.h>
int tolower(int c);
Inte ce Character to be converted
tolower
13—Character Classification and Conversion 177
Example Call
c = tolower('Q'); /* c will become ‘q' */
Returns
See Also
toupper
toupper <4
Purpose
Use the toupper function to convert the lowercase letter c to up-
percase.
Syntax
#include <ctype.h>
int toupper(int c);
int c; Character to be converted
Example Call
c = toupper('q'); /* c will become ‘Q' */
Returns
Example
Example 13-1 reads a line and converts it to uppercase. It calls
toupper on line 12.
Example 13-1 This example reads a line and converts it to
uppercase.
1:/* Read a line and convert it to uppercase */
2:#include <stdio.h>
3:#include <ctype.h>
4:
5:main®
6:f
7: char input(81], *p_in;
8: puts("Enter a line:");
OE gets (input);
toupper
178 ANSI C Data Processing
Introduction
Manipulating text is a major part of many computer applications.
The manipulation might involve text editing, word processing, or
that part of your application that reads commands typed by the
user and interprets them. Typically, you read a single line of com-
mand into a C string and interpret it. Depending on the syntax of
your application’s command set, the interpretation will involve
chores such as extracting the commands and parameters from the
string, comparing the command against entries in a stored table,
or copying the parameters into separate strings for later use. Al-
though C has no built-in operators for handling strings, the ANSI
C standard specifies a set of string manipulation routines that pro-
vides all the capabilities needed to process strings.
Strings in C
C has no basic data type for strings. Instead, strings are treated as
arrays of characters, each occupying a byte. By convention, the
end of a string in C is marked by a byte containing a null charac-
ter (\0). Because of this, C strings are known as null-terminated
strings or ASCIIZ (ASCII characters with a zero marking the end)
strings.
Declaring Strings in C
Since strings are treated as an array of characters, they can be de-
clared in your programs by a statement such as
char str1([81], str2(J="A string";
Here, str1 will be a string with room for 81 characters, but since
179
180 ANSI C Data Processing
char str2 [ ]
strlen(str2) =8
char *p__-str2 i j NULL byte marks
the end
Lexicographic Ordering
The string comparison routines compare and order strings as
they would have appeared in a dictionary. This ordering is
known as “‘lexicographic” ordering. The comparison is based
on the collating sequence of the characters in corresponding
bytes of the two strings. For the ASCII character set, the collating
sequence of the letters corresponds to their place in the lexicon.
Routine Description
Extracting Tokens
The C library has routines that help parse a string. The striok
function can get the tokens one by one. If you prefer, you can
use the routines strcspn and strspn to construct your own
parser, especially if your command language is much more com-
plicated than the one in our example. The strcspn function re-
turns the index of the first character (its location in the array) that
matches any one of the characters in a second string, while
strspn does just the opposite, returning the first character that
does not belong to the second string.
The strpbrk routine functions the same way as strcspn, but
it returns a pointer to the matched character rather than the in-
dex. The strstr function searches for the occurrence of one
string in another, and strchr and strrchr locate a single character
in a string. The strchr function searches from the string’s begin-
ning for the character, and strrchr searches from the end.
Cautions
& When allocating memory for a string, remember to count
the null character. If you are allocating memory to hold an-
other copy ofa specific string named, say, str, you can com-
pute the number of bytes you need by adding 1 to the value
returned from the call strlen(str).
& When copying a string to another, you must ensure that the
destination string has enough room to hold the incoming
characters. You will see no error messages if the copy opera-
tion continues beyond the last character of the destination
string, but the program is likely to fail in an unpredictable
way.
> If you use sirncpy to copy a specific number of bytes, less
than the length of the source string, to another one, the re-
sulting string will not have a null character automatically ap-
pended to it. So, you must append a \0 to convert the result
to a valid C string.
mblen <
Purpose
Use the mbien function to obtain the number of bytes that con-
stitute a multibyte character.
Syntax
#include <stdlib.h>
int mblen(const char *s, size_t n);
const char *s; Pointer to multibyte character whose length is to be
determined
Example Call
mbsize = mblen(p_mbchar, MB_CUR_MAX);
Returns
See Also
mbtowc, mbstowcs, wctomb, wcstombs
mblen
186 ANSI C Data Processing
ee
> mbstowcs
Purpose
Use the mbstowcs function to convert a sequence of multibyte
characters in mbs into a sequence of codes of wchar_t type and
store, at most, 7 codes in the array pwes.
Syntax ae
#include <stdlib.h>
size_t mbstowcs(wchar_t *pwcs, const char *mbs, size_t n);
wcha r_t *pwcs; Pointer to array where wide character results will be
stored
Example Call
mbstowcs(wc_array, mb_array, 10);
Returns
See Also
mblen, mbtowc, wctomb, wcstombs
> mbtowc
Purpose
Use the mbtowc function to convert a multibyte character at s to
wchar__t type and store the result in the array pwchar. If pwchar
is NULL, mbtowc will not save the resulting wide character. Also,
mbtowc will check at most characters in s when trying to lo-
cate a valid multibyte character.
Syntax
Hinclude <stdlib.h>
int mbtowc(wchar_t *pwchar, const char *s, size_t n);
wchar_t *pwchar; Pointer to array where the wide character equivalent
of the multibyte character will be stored
mbtowc
14—String and Buffer Manipulation 187
Example Call
mdc_size = mbtowc(pwc, mbchar, MB_CUR_MAX);
Returns
See Also
memchr <<
Purpose
Use the memchr function to search the first count bytes in the
buffer at the address buffer to find the first occurrence of the
character c.
Syntax
#include <string.h>
void *memchr(const void *buffer, int c, size_t count);
const void *buffer; Pointer to buffer in which search takes place
Example Call
/* Look for the first occurrence of ‘I’ in a 100 byte buffer
*/
first_i = memchr(start_address, ‘I', 100);
Returns
See Also
memcmp, strchr
memchr
188 ANSI C Data Processing
nl
> memcmp
Purpose
Use the memcmp function to compare the first count bytes of
buffer1 and buffer2.
Syntax
#include <string.h>
int memcmp(const void *buffer1, const void *buffer2,
size_t count);
const void *buffer1; Pointer to first buffer
Example Call
if (memcmp(buffer1, buffer2, sizeof(buffer1)) == 0)
printf("'The buffers are identical\n");
Returns
The memcmp function returns an integer less than, equal to, or
greater than zero according to whether the string buffer/ is lexi-
cographically less than, equal to, or greater than the string
buffer2.
See Also
strcoll, strcmp, strncmp
> memcpy
Purpose
Use the memcpy function to copy count bytes from the buffer at
address source to another buffer at dest. The behavior of
memcpy is undefined if the source and destination buffers over-
lap.
Syntax
#include <string.h>
void *memcpy(void *dest, const void *source, size_t count);
void xdest; Pointer to buffer to which data will be copied
const void *source; Pointer to buffer from which data will be copied
memcpy
14—String and Buffer Manipulation 189
Example Call
memcpy(dest, src, 80); /* Copy 80 bytes from dest to src */
Returns
See Also
SS
memmove <4
Purpose
Use the memmove function to copy count bytes from the buffer
at address source to another buffer at dest. The source and desti-
nation buffers may overlap.
Syntax
#include <string.h>
void *memmove(void *dest, const void *source, size_t count);
void *dest; Pointer to buffer to which data will be copied
const void *source; Pointer to buffer from which data will be copied
Example Call
memmove(dest, src, sizeof(src));
Returns
The memmove function returns a pointer to the destination
buffer dest.
See Also
memcpy, strcpy, strncpy
memset <
Purpose
Use the memset function to set the first count bytes in the buffer
to the character c.
memset
190 ANSI C Data Processing
Syntax
#include <string.h>
void *memset(void *buffer, int c, size_t count);
void *buffer; Pointer to memory where bytes are to be set
Example Call
memset
(big buffer, ‘\O0', 2048);
Returns
See Also
> streat
Purpose
Use the strcat function to append string2 to string1. The initial
character of string2 overwrites the null character at the end of
String].
Syntax
#include <string.h>
char *strcat(char *string1, const char *string2);
char *string1; Destination string
Example Call
char metool[7] = ''Me '';
strcat(metoo, "too'); /* Result is "Me too! */
Returns
See Also
Example
See Example 14-1 at the end of the chapter for a use of strcat to
concatenate strings.
strcat
14—String and Buffer Manipulation 191
eee ee a ee
Strchr <4
Purpose
Use the strcbr function to search for the first occurrence of the
character c in string. The terminating null character is included
in the search and may also be the character to be located.
Syntax
#include <string.h>
char *strchr(const char *string, int c);
const char *string; String to be searched
Example Call
cost_is = strchr("Estimated cost = $120", '$');
/* Now cost_is will be the string ''$120" */
Returns
See Also
strcmp <
Purpose
Use the strcmp function to compare the strings string/ and
string2 lexicographically.
Syntax
#include <string.h>
int strcemp(const char *string1, const char *string2);
const char *string1; First string
Example Call
if( strcmp(username, "root") != 0 ) exit (EXIT_FAILURE);
strcmp
192 ANSI C Data Processing
Returns
See Also
memcmp, strcoll, strncmp
> streoll
Purpose
Use the strcoll function to compare the strings string1 and
string2 after interpreting both according to the character collat-
ing sequence selected by the LC_COLLATE category of the cur-
rent locale.
Syntax
#include <string.h>
int strcoll (const char *string1, const char *string2);
const char *string1; First string
Example Call
if( strcoll(username, rootname) != 0 ) exit (EXIT_FAILURE);
Returns
See Also
memcmp, strncmp
> strcpy
Purpose
Use the strcpy function to copy the string string2 to the string
string!. The terminating null character of the second string is
also copied so that string/ becomes a copy of string2.
strcpy
14—String and Buffer Manipulation 193
Syntax
#include <string.h>
char *strcpy(char *string1, const char *string2);
char *string1; Destination string
Example Call
strcpy(command, "resize"');
Returns
See Also
memcpy, memmove, strncpy
strcspn <<
Purpose
Use the strcspn function to compute the length of the maximum
initial segment of string/ that consists entirely of characters not
in string2. This is the first substring in string/ that does not span
the character set string2.
Syntax
#include <string.h>
size_t strcspn(const char *string1, const char *string2);
const char *string1; String to be searched
Example Call
first_q = strcspn("soliloquy", "q"'); /* first_q = 6 */
Returns
See Also
strchr, strpbrk, strspn, strrchr
strcespn
194 ANSI C Data Processing
ne
> strerror
Purpose
Syntax
#include <string.h>
char *strerror(int errnum);
int errnum; Error number
Example Call
error_message = strerror(errno);
Returns
See Also
perror
.
> strien
Purpose
Use strlen to find the length of string in bytes, not counting the
terminating null character.
Syntax
#include <string.h>
size_t strlen(const char *string);
const char *string; String whose length is returned
Example Call
length = strlen(name);
Returns
strien
14—String and Buffer Manipulation 195
See Also
strcspn
strncat <4
Purpose
Use the strncat function to append the first m characters of
string2 to string, and terminate the resulting string with a null
character. The terminating null of the first string is removed and
string1 becomes the concatenation of the old string/ and the
first 2 characters of string2.
Syntax
#include <string.h>
char *strncat(char *string1, const char *string2, size_t n);
char *string1; Destination string
Example Call
char id[16] = "ID = ";
strncat(id, name, 10); /* id is first 10 char of name */
Returns
The strncat function returns a pointer to the concatenated
string, string/.
See Also
strcat, strcpy, strncpy
Example
Example 14-2 uses strncat to print a generate of characters.
——_____.___
strncmp
Purpose
Use the strncmp function to compare, at most, the first 2 charac-
ters of the strings string/ and string2.
strncmp
196 ANSI C Data Processing
Syntax
#include <string.h>
int strncmp(const char *string1, const char *string2, size_t
n);
const char *string1; First string
const char *string2; Second string :
Example Call
if(strncmp(command, "quit", 4) == 0) quit_program();
Returns
See Also
memcmp, strcmp, strcoll
> strncpy
»
Purpose
Use the strncpy function to copy the first 7 characters of the
string string2 to the buffer whose address is given by string/.
The copy is placed at the first character position of string/. Ifn
is less than the length of string2, no terminating null character is
appended to string1. However, if m exceeds the length of
string2, string1 is padded with enough null characters to make
it 2 bytes long. You should avoid situations where the 7 bytes
following string1 overlap string2, because the behavior of
strcpy with such arguments is not guaranteed to be correct.
Syntax
#include <string.h>
char *strncpy(char *string1, const char *string2, size_t n);
char *string1; Destination string
Example Call
strncpy(fname, '"'tmp12345678", 8); /* fname = "tmp12345" */
strncpy
14—String and Buffer Manipulation 197
Returns
See Also
gee ee ee ss a re tae
strpbrk <4
Purpose
Use the strpbrk function to locate the first occurrence in string/
of any character in string2.
Syntax
: ON
#include <string.h>
char *strpbrk(const char *string1, const char *string2);
const char *string1; String to be searched
Example Call
first_vowel = strpbrk(word, "aeiou'');
Returns
If successful, the strpbrk function returns a pointer to the first
occurrence of any character from string2 in string1. If the
search fails, strpbrk returns a NULL.
See Also
strchr, strcspn, strrchr, strspn
Example
Example 14-3 uses strpbrk to extract the first syllable in a word.
strrchr <4
Purpose
Use the strrchr function to locate the last occurrence of the char-
acter c in the string string. The terminating null character is in-
cluded in the search and it can be the character to be located.
Syntax
#include <string.h>
strrchr
198 ANSI C Data Processing
Example Call
char line_costl[] = '10 units at $1.20 ea. = $12.00";
total_cost = strrchr(line_cost, '$');
/* Now total_cost will be the string "$12.00" */
Returns
If cis found, strrchr returns a pointer to the last occurrence of it
in string. If the search fails, strrcbr returns a NULL.
See Also
strchr, strcspn, strpbrk, strspn
> strspn
Purpose
Use the strcspn function to compute the length of the maximum
initial segment of string/ that consists entirely of characters
from string2. This is the first substring in string/ that spans the
character set string2.
Syntax
Hinclude <string.h>
size_t strspn(const char *string1, const char *string2);
const char *string1; String to be searched
Example Call
char *input = "280ZX";
first_nondigit_at = strspn(input, '1234567890") ;
/* first_nondigit_at will be 3 */
Returns
See Also
strcspn, strpbrk
strspn
14—String and Buffer Manipulation 199
reer ee ee a ee
strstr <4
Purpose
Use strstr to locate the first occurrence of String string2 in
String1.
Syntax
#include <string.h>
char *strstr(const char *string1, const char *string2);
const char *string1; String to be searched
Example Call
char input(J="The account number is ACEG-88-07-11";
acc_no = strstr(input, '"ACEG'');
/* Now the string acc_no will be "ACEG-88-07-11"' */
Returns
See Also
strchr, strcespn, strpbrk
strtok <4
Purpose
Use the strtok function to retrieve a token, or substring, from
string1. The token is marked by delimiting characters given in
the second string argument string2. All tokens in a particular
string (string/) can be extracted through successive calls to
strtok in the following way. Make the first call to strtok with the
string to be “‘tokenized” as the first argument. As the second ar-
gument, provide a string comprising the delimiting characters.
After that, call strtok with a NULL as the first argument and the
delimiting characters appropriate for that token in the second
string. This tells strtok to continue returning tokens from the old
stringl.
Note that the set of delimiters can change in each call to
strtok. Also, in the process of separating tokens, strtok modifies
string/. It inserts null characters in the place of delimiters to
convert tokens to strings.
strtok
200 ANSI C Data Processing
Syntax
#include <string.h>
char *strtok(char *string1, const char *string2);
char *string1; String from which tokens are returned .
Example Call
next_token = strtok(input, "\t, ');
Returns
See Also
strcspn, strpbrk, strspn
Example
Example 14-4 shows a simple program that extracts tokens from
a String.
> strxfrm
Purpose
Use the strxfrm function to transform string2 to a new form
(string1) so that if strcmp is applied to the two transformed
strings the returned result is the same as that returned when
strcoll is applied to the original strings. You can place no more
than maxchr characters in string. lf maxcbr is 0, string] can be
a NULL. In this case, the return value is the length of the trans-
formed version of string2.
Syntax
#include <string.h>
size_t strxfrm(char *string1, char *string2, size_t maxchr);
char *string1; String where transformed version of string2 is returned
char *string2; String to be transformed
size_t maxchr; Maximum number of characters to be placed in string]
Example Call
strxfrm(s_xfrm, s_original);
strxfrm
14—String and Buffer Manipulation 201
Returns
See Also
strcmp, strcoll
ee ee IN Ca ANT IS
wctomb <4
Purpose
Use the wctomb function to convert wchar, a character of wchar_t
type to a multibyte character and store the result in the array s. At
most, MB_CUR_MAX characters are stored in the array s.
Syntax
#include <stdlib.h>
int wetomb(char *s, wchar_t wchar);
char *s; Pointer to start of array where the multibyte equivalent of
wchar is returned
Example Call
wetomb(mb_char, wchar);
Returns
See Also
westombs <
Purpose
Use the wcstombs function to convert a sequence of codes of
wchar__t type, given in the array pwes, into a sequence of mul-
tibyte characters and to store, at most, ” bytes in the array mbs.
westombs
202 ANSI C Data Processing
Syntax
#include <stdlib.h>
size_t wcstombs(char *mbs, const wchar_t *pwes, size_t n);
const char *mbs; Pointer to array where mulibyte characters will be
stored
Example Call
westombs(mb_array, wc_array, 10*MB_CUR_MAX);
Returns
See Also
wcstombs
14—String and Buffer Manipulation 203
abcd
abcde
abcdefghi jklmnopqrstuvwxyz
1:#include <stdio.h>
2:#include <string.h>
3:char result(40) = ''a!'s
4:char rest(] = "bcdefghi jklmnopqrstuvwxyz''s
Ssunsigned length = sizeof(rest)/sizeof(char);
6:main()
7:
8: unsigned i;
9: for(i = 0; i<length; i++, result(1}='\0')
10: {
ARIE strncat(result, rest, i);
12:/* Show the current result */
AS printf('"'%s\n", result):
14: }
{heres
Introduction
Searching and sorting are commonplace. All commercial data
base programs have these capabilities, for instance. If you are im-
plementing your own data base program, you invariably need
search and sort capabilities. For example, if your data base con-
tains the names and addresses of the customers of your com-
pany, you might want to search the data base for information
about a certain customer. And you might want to print labels for
a mailing for all entries in your data base sorted by zip code. If
you are developing your data base in C, the ANSI C standard
eases your job by providing two library routines for sorting and
searching lists in memory.
Sorting
The typical sort operation you will encounter involves a data lay-
out like that shown in Figure 15-1. You have an array of pointers,
each of which contains the address of a data structure (for ex-
ample, a structure with fields containing the name, address, and
zip code for a customer). Sorting is done not by rearranging the
data records themselves, which would be inefficient, but by re-
arranging the pointers to cause a particular field in the data struc-
205
206 ANSI C Data Processing
ture (called the “key” for the sort) to appear in either ascendant
or descendant position. Figure 15-1 shows the original list and
the list after it was sorted with the zip code (the key field) ascen-
dant. Notice that only the pointers were rearranged; the data
structures stayed put. This improves sorting speed because the
pointers are much smaller than the structures themselves, even
though the pointers require extra storage space.
Address:
Zip: 94115
Name:
Zip: 10020 B
. Address:
Zip: 95066 y
Zip: 98073
your definition, the sort function gsort will sort the array in
as-
cending order.
Although the ANSI standard does not specify which algo-
rithm to use, typical implementations of qsort use the well-
known “quicksort” algorithm, a popular, general-purpose sort
algorithm invented by C. A. R. Hoare in 1962.
Searching
The ANSI C library includes the bsearch function, which
searches an array for an item using a binary search algorithm. Al-
though the ANSI standard does not enforce a specific search al-
gorithm, most compilers implement bsearch. Like quicksort,
binary search uses a divide-and-conquer approach analogous to
looking up a word in the dictionary. You flip to a page around the
middle of the dictionary and if the words on that page occur
later in alphabetic order than the word you are looking for, you
repeat the search in the first half of the dictionary. Ofcourse, this
method works only because the dictionary is already sorted ina
particular order.
The ANSI standard does require that the array must be
sorted in ascending order of the key field to be searched. This is
necessary for the binary search algorithm. The binary search be-
gins by comparing the value of the key field in the middle entry
of the array with the value being sought. If the entry has a value
either too high or too low, this search step is repeated on the
upper half or lower half of the array, respectively. Thus at every
step of the search you reduce the length of the array to be
searched by half, allowing a large array to be searched very
quickly.
string. You can use a routine such as strcmp to perform the com-
parison inside compare( ).
Information
you provide |
Size of each element |
size = sizeof(char*)——+
|__
|
|
Comparison |
routine |
compare PEE ERAN
|
(char**
x* | Command-line
ona | arguments
|
|
Base of array _
char*
Number
of elements
_ unsigned” | numelem
Further Reading
Search and sort algorithms are covered in every computer Ssci-
ence text On data structures and algorithms. An entire volume by
Knuth! deals with sort and search algorithms alone. For a shorter
introduction to these algorithms, consult the books by Sedge-
wick? and Tremblay and Sorenson’.
1. Donald E. Knuth, The Art of Computer Programming, Vol-
ume 3: Sorting and Searching, Addison-Wesley Publishing
Co., Reading, MA, 1973, 744 pages.
2. Robert Sedgewick, Algorithms, Addison-Wesley Publishing
Co., Reading, MA, 1983, 551 pages.
3. Jean-Paul Tremblay and Paul G. Sorenson, An Introduction
to Data Structures with Applications, Second Edition,
McGraw-Hill, Inc., New York, NY, 1984, 861 pages.
15—Searching and Sorting 209
bsearch <
Purpose
Use the bsearch function to search a sorted array beginning at
the address base and comprising num elements, each of a size of
width bytes. The argument key points to the value being sought.
See the tutorial section for more on the function pointer com-
pare that you must provide to bsearch. Note that you can use the
qsort routine to sort the array before calling bsearch.
Syntax
#include <stdlib.h>
void *bsearch(const void *key, const void *base, size_t num,
size_t width,
int (*compare) (const void *elem1, const void
xelem2));
Example Call
int mycompare(const void *, const void *);
result = (char **) bsearch((const void *) keyword
(const void *)envp,
(size_t)count,
(size_t)sizeof(char *),
mycompare);
Returns
The bsearch function returns a pointer to the first occurrence of
the value ey in the array. If the value is not found, bsearch te-
turns a NULL.
See Also
qsort
Example
Line 29 in Example 15-1 calls bsearch to search fora keywordina
sorted array.
bsearch
210 ANSI C Data Processing
> qsort
Purpose
Use the gsort function to sort an array beginning at the address
base and comprising num elements, each of size width bytes.
During the sort, gsort compares pairs of elements from the array
by calling a routine whose address you provide in the argument
compare. This function should accept two arguments, elem1
and elem2, each a pointer to an element in the array. See the tuto-
rial section for information on how this function should behave.
Syntax
#include <stdlib.h>
void qsort(const void *base, size_t num, size_t width,
int (*compare) (const void *elem1, const void
xelem2));
const void *base; Pointer to beginning of array being sorted
Example Call
int compare(const void *, const void *);
qsort((void *) envp, (size_t)count,
(size_t)sizeof(char *), compare);
See Also
bsearch
Example
Line 19 in Example 15-1 calls gsort to sort an array.
Example 15-1 In Microsoft C under MS-DOS, the main func-
tion is invoked with three arguments, the first
two give the number of strings in the com-
mand line and the command line itself. The
third argument is the MS-DOS environment
table, which is also an array of strings. Write a
program that accepts a keyword on the com-
mand line and uses bsearch to search for the
string beginning with this keyword in the en-
vironment table. The program first sorts the
environment table using gsort, and then
prints it and then calls bsearch to perform the
qsort
15—Searching and Sorting 211
Found PROM in
PROMPT=$p$g
Time and Date Functions
Routine Description
213
214 ANSI C Data Processing
System dat
end time
implementation
dependent encoded
ctime( )
int tm__sec
inta a a _
Thu Nov 26 17:02:39 1987 \n \0 5
int tn__mday ‘| asctime( ) String
eae
pe
wee.
int tm__wday Ve
Elapsed Time
Sometimes you have to compute the time elapsed between two
events. The difftime function returns the difference of two val-
ues Of type time _t in seconds. The clock function returns the
number of clock ticks used by the process so far. The number of
ticks per second is defined in the constant CLK_TCK (in file
time.h). Its actual value is implementation dependent.
Cautions
Pm The functions gmtime and localtime use a single structure
of type tm to store the time. Each call to either function
Overwrites the result of the previous call.
Pe The ctime and asctime functions also use a single character
string to store results. Thus a call to one overwrites the re-
sult of the previous call.
asctime <<
Purpose
Use the asctime function to convert to a character string the
value of a time stored in the structure of type tm at the address
time. The structure tm is defined in time.h as
struct tm
{
int tm_sec; /* seconds after the minute - Shera
i;
asctime
216 ANSI C Data Processing
Syntax
#include <time.h>
char *asctime(struct tm *time);
struct tm *time; Pointer to a structure containing time to be converted
to a string
Example Call
printf("'The time is %s\n", asctime(&timedata));
Returns
See Also
> clock
Purpose
Use clock to obtain the amount of processor time used by the
current process in “number of ticks.” The constant CLK_TCK,
defined in time. h, is the number of ticks per second, so the value
returned by clock should be divided by CLK_TCK to get the
elapsed processor time in seconds.
Syntax
Winclude <time.h>
clock_t clock(void);
Example Call
ticks_now = clock();
Returns
See Also
difftime, time
16—Time and Date Functions 217
SSS
ctime <<
Purpose
Use the ctime function to convert to a character String the value
of time stored in the variable of type time_t at the address
timer. Calling ctime is equivalent to the call asctime(localtime
(timer)).
Syntax
#include <time.h>
char *ctime(const time_t *timer);
const time_t *timer; Pointer to calendar time
Example Cali
printf("Current time = %s\n", ctime(&bintime));
Returas
See Also
asctime, time
Example
See Example 16-1 at the of the chapter. Line 11 in that example
uses clime to convert an encoded time _t value to a string.
ditttime<
Purpose
Use the difftime function to compute the difference between
two time values, time2 and time1, both of type time _t.
Syntax
#include <time.h>
double difftime(time_t time2, time_t time);
time_t time2; Value of time from which time will be subtracted
Example Call
seconds_used = difftime(oldtime, newtime);
218 ANSI C Data Processing
Returns
The difftime function returns the elapsed time, time2-time1/, in
seconds as a double-precision number.
See Also
clock, time
a gmtime
Purpose
Use the gmtime function to break down a time value of type
time __t stored at the location time into year, month, day, hour,
minutes, seconds, and several other fields that it saves in a struc-
ture of type tm, which is maintained internally. The structure tm
is defined in time.b and shown in asctime. The fields set up by
gmtime correspond to GMT.
Syntax
#include <time.h>
struct tm *gmtime(const time_t *time);
const time_t *time; Pointer to calendar time
¥ Example Call
t_gmt = gmtime(&bintime);
Returns
See Also
aa a TEE
> localtime
Purpose
Use the /ocaltime function to break down the value of time of
type time_t stored at the location time into year, month, day,
hour, minutes, seconds, and several other fields that it saves in a
structure of type ¢m, which is maintained internally. The struc-
ture ¢m is defined in time. and is shown in the reference pages
localtime
16—Time and Date Functions 219
Syntax
#include <time.h>
struct tm *localtime(const time_t *time);
const time_t *time; Pointer to stored calendar time
Example Call
t_local = localtime(&bintime);
Returns
See Also
Example
Line 14 in Example 16-2 uses /ocaltime to convert a time _t value
into its component parts.
mktime <4
Purpose
Use the mktime function to convert the local time in the struc-
ture of type tm at the address timeptr to a value of type time _t.
Essentially, the local time given in components of year, month,
day, and so on, is converted to number of seconds elapsed since
00:00:00 hours GMT, January 1, 1970. This is the same format in
which time returns the current time and is the format used in the
argument to the functions ctime, difftime, and localtime.
Two fields in the structure of type tm are ignored by
mktime. These are the tm_wday and tm_yday fields, denoting
the day of the week and the day of the year, respectively. The
mktime function sets the fields in the t7 structure to appropriate
values before returning.
Syntax
#include <time.h>
time_t mktime(struct tm *timeptr);
struct tm *timeptr; Pointer to structure of type tm where local time is
stored
Example Call
bintime = mktime(&timebuf) ;
mktime
220 ANSI C Data Processing
Returns
See Also
asctime, time
Example
Example 16-2 uses mktime to implement a utility that prints the
date it will be any number of days from the current day.
> stritime
Purpose
Use the strftime function to format a time broken down to com-
ponents in a tm structure whose address is in timeptr into a
string whose address is provided in str. At most, maxsize charac-
ters are placed in the string. The formatting is done according to
codes, listed in Table 16-3, which are given in the string format_
string. The argument format_string is expected to be in mul-
* tibyte characters. Like sprintf, the formatting codes begin with a
% . Characters that do not begin with a % are copied unchanged
to str. The LC_ TIME category of the program’s locale affects the
behavior of strftime.
Syntax
#include <time.h>
size_t strftime(char *str, size_t maxsize, const char
*format_string,
const struct tm *timeptr);
char *str; Pointer to array of characters where result is placed
Example Call
/* Produce the standard output: Thu Jul 21 19:02:39 1988
strftime(s, 80, "%a %b %c\n", &tptr);/
16—Time and Date Functions 221
Returns
See Also
asctime, ctime, gmtime, localtime, time
time<4
Purpose
Use the time function to get the current date and time (calendar
time) encoded as an implementation-dependent value of type
time
222 ANSI C Data Processing
time _t. If the pointer timeptr is not null, the encoded time is
copied to the location whose address is in timeptr.
Syntax
#include <time.h>
time_t time(time_t *timeptr); 3
time_t *timeptr; Pointer to variable where result is returned
Example Call
time(&bintime);
Returns
See Also
Example
Line 7 in Example 16-1 and line 13 in Example 16-2 call time to
get the current calendar time in encoded form.
Example 16-1 This program prints the current date and
time.
* 1:#include <stdio.h>
2:#include <time.h>
3:main()
4:{
53 time_t tnow;
6:/* Get the time in encoded form */
(3 time(&tnow);
8:/* Convert the time to a string and print it. This
9: * will be your local time.
TORR #Y)
Aine printf("'Current time = %s\n"', ctime(&tnow));
eRe
time
16—Time and Date Functions 223
' ai
Ta my
oh \ i.
Edsmiple van :
eae |
aattiivens hnteonat| vo9
Weivoe OA
‘i ~ boleg
ty Fhe ee ee
a s i J ji6 we Wire
:
BZ « ‘ a
ahead a a
te an i, ;
! See Exclamation points AND operators, 26-27
” See Double quotes Appending
# See Pound sign opening files for, 74
% See Percent sign of strings, 182-183, 202-203
& See Ampersands Arguments. See Parameters
” See Single quotes Arithmetic operators, 25-26
( ) See Parentheses Arrays, 18-19
* See Asterisks elements of, 26
+ See Plus sign memory allocation for, 130
, See Commas and pointers, 20
— See Minus sign sorting and searching of,
. See Periods 205-208
/ See Slashes strings as, 179-180
: See Colons ASCIIZ strings, 179
; See Semicolons Asctime function, 213-216
« See Less than sign Asin function, 152, 153, 155-156
= See Equal sign Assert function, 113-114
> See Greater than sign Assert. standard header file, 49
? See Question marks Assignment operators, 26-28
] See Square brackets Associativity of operators, 27-28
See Backslashes Asterisks (*)
* See Carets in format specifications, 91
— See Underscore for indirection, 26-27
{ } See Braces — for multiplication, 25, 27
| See Vertical bars Atan function, 152, 153, 156
~ See Tildes Atan2 function, 152, 153,
156-157
A Atexit function, 112-113, 115, 123
Atof function, 141-142
\a for alert, 10 Atoi function, 141, 143
A file access mode, 74 Atol function, 141, 143
%a format code for time, 221 Auto storage class, 23, 32-33
Abort function, 60, 112-114
Abs function, 152-155
Access modes, file, 74 B
Acos function, 152, 153, 155
Addition, 25, 27 \b for backspace, 10
Address operator, 19, 26-27 B file access mode, 74
Addresses and pointers, 19 %b format code for time, 221
Alert, escape sequence for, 10 Backslashes (\)
Ampersands (&) escape sequence for, 10
as address operator, 19, 26-27 for escape sequences, 9
in AND operators, 26-27 trigraph sequences for, 9
226 Essential Guide to ANSI C
L Loops
and continue, 35
L qualifier in format specifica- do-while, 28, 33, 35-36
tions, 67, 85, 91 for, 29, 33, 39
Labels while, 30, 33, 35, 48
with goto, 29 Lowercase, conversion of charac-
with switch, 34-35, 44-45 ters to, 174
Labs function, 152, 153, 162-163 L_tmpnam constant, 52, 63
LC_ALL constant, 52, 112
LC_COLLATE constant, 52, 112, M
183 %m format code for time, 221
ee constant, 52, 112, Macros
18 in #include directives, 12
LC_MONETARY constant, 52, library, 50-55
112 predefined, 15
LC_NUMERIC constant, 52, 112 processing of, 12-13
Lconv structure, 54, 112, 117 variable argument, 125-128
LC_TIME constant, 52, 112 Main function, 8, 30
LDBL_ DIG constant, 52 Malloc function, 25, 130, 133
LDBL_ EPSILON constant, 52 Mantissas in floating-point num-
LDBL_MANT_DIG constant, 52 bers, 149-151, 162
LDBL_ MAX constant, 52 Math coprocessors, 140
LDBL_MAX_ 10_ EXP constant, Math functions, 149-154
52 Math.h standard header file, 49,
LDBL_MAX_ EXP constant, 52 151
LDBL_MIN constant, 52 Matrices, 19
LDBL_MIN_ 10_EXP constant, MB_CUR_MAX constant, 53
53 Mblen function, 181, 183, 185
LDBL_MIN_
EXP constant, 53 MB_LEN_
MAX constant, 53
Ldexp function, 152, 163 Mbstowcs function, 181, 184,
Ldiv function, 152, 153, 163-164 186-187
Ldiv_t data structure, 54, 163 Mbtowc function, 181, 184, 186
Length of strings, functions for, Members of structures, 21, 26
182-183 Memcbr function, 181, 187
Less than sign (<) Memcmp function, 181, 183, 188
as relational operator, 26-27 Memcpy function, 181, 183,
as shift operator (<<), 26-27 188-189
in trigraph sequences, 9 Memmove function, 181, 183, 189
Lexicographic ordering, 180 Memory allocation, 8, 17,
Library, standard, 49-55 129-131
Lifetime of variables, 17, 22-25 dynamic, 19-20
Limits.b standard header file, 18, for strings, 185
49 Memset function, 181, 189-190
#line directive, 15 Microsoft C 5.1, 10
Line 1/O, functions for, 64 Minus sign (—)
_ _LINE_ _ macro, 15 in arrow operator (—)), 26-27
Local declarations and variables, for decrement operation (—),
Se 25252 Ze
Locale of programs, 111-113 for left justification, 85
Localeconv function, 112-113, for negation, 26-27
116-118 for subtraction, 25, 27
Locale.b standard header file, 49, in trigraph sequences, 9
111, 117 Mktime function, 213-214,
Localtime function, 213-214, 219-220, 222-223
218-219 Modf function, 152, 164-165
Log function, 152, 153, 164 Modularity and file inclusion, 11
Log10 function, 152, 153, 164 Modulo operation, 25
Logical operators, 26-27 Monetary formatting and /o-
Long qualifier, 17-18, 40-41, 66, caleconv, 112
85, 91 Multibranching with switch,
conversions with, 142 44-45
Longjmp function, 113, 118, Multibyte characters, 9-10,
123-124 180-182, 184
LONG
_ MAX constant, 53 Multidimensional arrays, 19
LONG _MIN constant, 53 Multiplication, 25, 27
230 Essential Guide to ANSI C
‘ie 4 LA “Ry
a -
, ae ee oe a
(a0 a Soh
i
= i Hot BA
: Ae . Ss t ue cht &:¢- TP te
. 5 ‘ - "°
é ; even aE :
: ‘wae
oP ae j pa
|| 7 wee
py
|
?
2. r
; i
4 ¥
+ re
4 ©
hi ~ \s
by nil
. =,
wo ee
‘ - 7
™~
s mt
>
4
seit :
. . ’ j |
ee a
i "
= 1
4 F " 4
1 ie FF
‘
tok fre 4 t j
~
4 i 4 ‘e 2
“ ie
& ~x j
‘
‘ '
|: rs
. .
‘ 7 i
¥ i]
. 2-% }
i) Balerea a oe i e
Man. aera
= (APA sy WSs +0!
ANSi € Library Routines by Subject
$7.95 US/22673
Sf ISBN O-b?e2-
HOWARD W. SAMS «
& COMPANY |
A Division of Macmillan, Inc.
4300 West 62nd Street
Indianapolis, Indiana 46268 USA 9 "780672 "226731