Lint
From:     http://www.lysator.liu.se/c/c-faq/index.html#EoPS




Section 12. Library Subroutines

12.1: Why does strncpy not always place a '\0' termination in the
destination string?

strncpy was first designed to handle a now-obsolete data structure, the
fixed-length, not-necessarily-\0-terminated "string."  strncpy is admittedly
a bit cumbersome to use in other contexts, since you must often append a
'\0' to the destination string by hand.

12.2: I'm trying to sort an array of strings with qsort, using strcmp as the
comparison function, but it's not working.

By "array of strings" you probably mean "array of pointers to char."  The
arguments to qsort's comparison function are pointers to the objects being
sorted, in this case, pointers to pointers to char.  (strcmp, of course,
accepts simple pointers to char.)

The comparison routine's arguments are expressed as "generic pointers,"
const void * or char *.  They must be converted back to what they "really
are" (char **) and dereferenced, yielding char *'s which can be usefully
compared.  Write a comparison function like this:

	int pstrcmp(p1, p2)	/* compare strings through pointers */
	char *p1, *p2;		/* const void * for ANSI C */
	{
		return strcmp(*(char **)p1, *(char **)p2);
	}

Beware of the discussion in K&R II Sec. 5.11 pp. 119-20, which is not discussing Standard library qsort.

12.3: Now I'm trying to sort an array of structures with qsort.  My comparison routine takes pointers to structures, but the compiler complains that the function is of the wrong type for qsort.  How can I cast the function pointer to shut off the warning?

The conversions must be in the comparison function, which must be declared as accepting "generic pointers" (const void * or char *) as discussed in question 12.2 above. The code might look like

        int mystructcmp(p1, p2)
        char *p1, *p2;          /* const void * for ANSI C */
        {
                struct mystruct *sp1 = (struct mystruct *)p1;
                struct mystruct *sp2 = (struct mystruct *)p2;
                /* now compare sp1->whatever and sp2-> ... */
        }

(If, on the other hand, you're sorting pointers to structures, you'll need
indirection, as in question 12.2:

        sp1 = *(struct mystruct **)p1 .)

12.4: How can I convert numbers to strings (the opposite of atoi)?  Is there
an itoa function?

Just use sprintf.  (You'll have to allocate space for the result somewhere
anyway; see questions 3.1 and 3.2.  Don't worry that sprintf may be
overkill, potentially wasting run time or code space; it works well in
practice.)

References: K&R I Sec. 3.6 p. 60; K&R II Sec. 3.6 p. 64.

12.5: How can I get the current date or time of day in a C program?

Just use the time, ctime, and/or localtime functions.  (These routines have been around for years, and are in the ANSI standard.)  Here is a simple example:

	#include 
	#include 

	main()
	{
		time_t now = time((time_t *)NULL);
		printf("It's %.24s.\n", ctime(&now));
		return 0;
	}

References: ANSI Sec. 4.12 .

12.6: I know that the library routine localtime will convert a time_t into a
broken-down struct tm, and that ctime will convert a time_t to a printable
string.  How can I perform the inverse operations of converting a struct tm
or a string into a time_t?

ANSI C specifies a library routine, mktime, which converts a struct tm to a
time_t.  Several public-domain versions of this routine are available in
case your compiler does not support it yet.

Converting a string to a time_t is harder, because of the wide variety of
date and time formats which should be parsed.  Some systems provide a
strptime function; another popular routine is partime (widely distributed
with the RCS package), but these are less likely to become standardized.

References: K&R II Sec. B10 p. 256; H&S Sec. 20.4 p. 361; ANSI Sec. 4.12.2.3 .

12.7: How can I add n days to a date?  How can I find the difference between
two dates?

The ANSI/ISO Standard C mktime and difftime functions provide some support
for both problems.  mktime() accepts non-normalized dates, so it is
straightforward to take a filled-in struct tm, add or subtract from the
tm_mday field, and call mktime() to normalize the year, month, and day
fields (and convert to a time_t value).  difftime() computes the difference,
in seconds, between two time_t values; mktime() can be used to compute
time_t values for two dates to be subtracted.  (Note, however, that these
solutions only work for dates in the range which can be represented as
time_t's, and that not all days are 86400 seconds long.)  See also questions
12.6 and 17.28.

References: K&R II Sec. B10 p. 256; H&S Secs. 20.4, 20.5 pp. 361-362; ANSI Secs. 4.12.2.2, 4.12.2.3 .

12.8: I need a random number generator.

The standard C library has one: rand().  The implementation on your system
may not be perfect, but writing a better one isn't necessarily easy,
either.

References: ANSI Sec. 4.10.2.1 p. 154; Knuth Vol. 2 Chap. 3 pp. 1-177.

12.9: How can I get random integers in a certain range?

The obvious way,

        rand() % N

(where N is of course the range) is poor, because the low-order bits of many
random number generators are distressingly non-random.  (See question
12.11.)  A better method is something like

        (int)((double)rand() / ((double)RAND_MAX + 1) * N)

If you're worried about using floating point, you could try

        rand() / (RAND_MAX / N + 1)

Both methods obviously require knowing RAND_MAX (which ANSI defines in ),
and assume that N is much less than RAND_MAX.

12.10: Each time I run my program, I get the same sequence of numbers back
from rand().

You can call srand() to seed the pseudo-random number generator with a more
random initial value.  Popular seed values are the time of day, or the
elapsed time before the user presses a key (although keypress times are hard
to determine portably; see question 16.10).

References: ANSI Sec. 4.10.2.2 p. 154.

12.11: I need a random true/false value, so I'm taking rand() % 2,  but it's
just alternating 0, 1, 0, 1, 0...

Poor pseudorandom number generators (such as the ones unfortunately supplied
with some systems) are not very random in the low-order bits.  Try using the
higher-order bits.  See question 12.9.

12.12 I'm trying to port this old program.  Why do I get "undefined
external" errors for ..:
Those routines are variously obsolete; you should instead...:

index?
    use strchr. 
rindex?
    use strrchr. 
bcopy?
    use memmove, after interchanging the first and second arguments (see
also question 5.15). 
bcmp?
    use memcmp. 
bzero?
    use memset, with a second argument of 0. 

12.13: I keep getting errors due to library routines being undefined, but
I'm #including all the right header files.

In some cases (especially if the routines are nonstandard) you may have to
explicitly ask for the correct libraries to be searched when you link the
program.  See also question 15.2.

12.14: I'm still getting errors due to library routines being undefined,
even though I'm using -l to request the libraries while linking.

Many linkers make one pass over the list of object files and libraries you
specify, and extract from libraries only those modules which satisfy
references which have so far come up as undefined.  Therefore, the order in
which libraries are listed with respect to object files (and each other) is
significant; usually, you want to search the libraries last.  (For example,
under Unix, put any -l switches towards the end of the command line.)

12.15: I need some code to do regular expression matching.

Look for the regexp library (supplied with many Unix systems), or get Henry
Spencer's regexp package from ftp.cs.toronto.edu in pub/regexp.shar.Z (see
also question 17.12).

12.16: How can I split up a command line into whitespace-separated
arguments, like main's argc and argv?

Most systems have a routine called strtok, although it can be tricky to use
and it may not do everything you want it to (e.g., quoting).

References: ANSI Sec. 4.11.5.8; K&R II Sec. B3 p. 250; H&S Sec. 15.7; PCS p. 178.