McIDAS Programmer's Manual
Version 2003
[Search Manual]
[Table of Contents] [Go
to Previous] [Go
to Next]
Conversion
utilities
The
McIDAS-X library provides many practical conversion utilities for your applications.
These functions were developed because the standard Fortran and C libraries
didn't provide sufficient routines for performing the conversions needed in
McIDAS-X.
This
section describes the functions available in for performing these tasks:
- Manipulating
information at the byte level
- Handling
character strings
- Converting
day and time formats
- Converting
latitude and longitude formats
- Converting
physical units such as speed and temperature
|
For
additional information about the conversion functions described in this
section, see the online man pages provided with the McIDAS-X software. |
Byte-
and word-level manipulation
When writing
applications for McIDAS-X, you may find it necessary to manipulate information
at the byte level. This section describes the McIDAS-X library functions that
provide byte-level manipulation for Fortran routines and gives examples of
specific byte-level operations.
When writing
C functions, you can usually use the byte manipulation routines provided in
the standard C library. However, you may also want to use some of the functions
presented here since they have special features. Most of the byte moving routines
in this section are Fortran-callable functions written in C that use the byte
manipulation routines provided with the standard C library.
This
section contains some terms that may be unfamiliar to you. They are defined
below.
- A buffer is
any memory storage.
- A byte is
an 8-bit memory segment; a half-word is a 16-bit
memory segment; a word is a 32-bit memory segment.
- An element refers
to a collection of one or more bytes.
- 0-based is
a counting sequence that begins with zero; 1-based is
a counting sequence beginning with the number one.
- Big-endian and network-byte-order are
used interchangeably
to mean the most significant byte in a word comes first; little-endian means
the least significant byte is first. For example, the byte ordering for the
integer value 12 appears as 0000000c on big-endian machines and 0c000000
for little-endian machines.
- Memory
overflow refers to writing beyond the memory allocated for a variable.
Be careful
when using the byte manipulation functions below. Most do not protect against
memory overflow.
Fortran function
|
Description
|
alit |
copies
four bytes of a character string to a single precision floating-point
variable |
clit |
copies
four bytes of an integer value to a 4-character string variable |
crack |
copies
a specified number of consecutive bytes from a source buffer into an
array of words; each word is a 32-bit- long memory segment; the resulting
byte values are stored in the least significant byte for each element
of the word array |
dlit |
copies
eight bytes of a character string to a double precision floating-point
variable |
ic |
returns
the value at a specific byte location (0-based) in a buffer |
lit |
copies
four bytes of a character string to a 1-word integer variable |
movb |
copies
a number of bytes from a source buffer to a specified, 0-based offset
in a destination buffer |
movblk |
copies
a number of elements of a specified size from a source buffer to a destination
buffer with incremental offsets for both the source and destination buffers
(0-based) |
movc |
copies
a number of bytes beginning at a specified byte location in a source
buffer (0-based) to a specified offset in a destination buffer (0-based) |
movcw |
copies
the entire contents of a character string buffer to an integer buffer |
movh |
copies
a number of half-words from a source buffer to a destination buffer with
half-word increments |
movpix |
copies
a number of elements from a source buffer to a destination buffer with
incremental offsets for both the source and destination buffers |
movw |
copies
a number of words from a source buffer to a destination buffer |
movwc |
copies
the contents of an integer buffer to a character string buffer, copying
as many bytes as can be stored in the destination string |
mpixel |
copies
elements of a specified size in a source buffer to a destination buffer
with elements of a specified size |
mpixtb |
like
mpixel, but additionally converts variable-sized elements in a buffer
based on a lookup table |
pack |
moves
the least significant byte from each element of a word array and compresses
it into consecutive bytes in a buffer |
pack2 |
moves
the least significant byte from each element of a half-word array and
compresses it into a consecutive byte string |
stc |
places
a byte value into a specified, 0-based byte location in a buffer |
swbyt2 |
switches
the byte ordering of a half-word to big-endian; this function has no
effect on a machine that uses big-endian as its native storage format |
swbyt4 |
switches
the byte ordering of a word to big-endian; this function has no effect
on a machine that uses big-endian as its native storage format |
zeros |
sets
a number of bytes in an array to zero |
Below are some
code segments demonstrating the byte manipulation utilities. Similar functions
are grouped together. The more commonly used functions are discussed first.
Note that some of the byte manipulation functions will behave differently on
big- and little-endian machines. All the examples in this section assume big-endian.
|
For
more information about these byte manipulation functions, see the online
man pages provided with the McIDAS-X software. |
Extracting
and inserting a byte value
The ic function
lets you extract the value of individual bytes within a memory segment, as
shown in the sample code below. It is useful when checking for ASCII control
characters in a byte stream, for example.
c--- function ic example
integer oldval
integer val
data oldval/z'abcdef01'/
val = 0
c--- extract the second byte, 0-based, from 'oldval' and
c--- place the result in 'val'
val = ic (oldval, 2)
c--- the resulting value in 'val' will be:
c--- hex
c--- 000000ef
|
The stc function
lets you insert a byte value in a particular location in a memory segment.
It is useful for substituting control characters with a blank before sending
the output to a printer, for example.
c--- function stc example
integer src
data src/z'000000ba'/
val = 0
c--- place the byte value from 'src' into the second byte,
c--- 0-based, in 'val
call stc (src, val, 2)
c--- the resulting value in 'val' will be:
c--- hex
c--- 0000ba00
|
Switching
the byte ordering
When you
develop applications that read data from a remote data file or data stream,
you usually need to know the byte ordering of the source data. In general,
IBM-RISC, SUN, SGI and HP are big-endian machines, and DEC and Intel are
little-endian machines.
The swbyt2 and swbyt4 functions
have no effect on big-endian machines; however, they flip the bytes on little-endian
machines, making the least significant byte the most significant byte. Because
this byte ordering is transparent, you only have to maintain one set of source
code for both types of architecture. When transferring data between systems,
call swbyt# before writing and after reading.
Use the swbyt# calls
on known integer values only; don't use them to process character strings.
c--- function swbyt4 example
integer src(2)
data src/Z'abcdef01',Z'23456789'/
c--- if applicable, flip the 2 elements of the array 'src'
c--- into network-byte ordering.
call swbyt4 (src, 2)
c--- Because swbyt4 is a machine-dependent operation the
c--- outcome of this call will vary. On big-endian machines,
c--- swbyt4 will not modify the values in the buffer 'src'.
c--- On little-endian machines it will.
c--- big-endian little-endian
c--- src() input value input value output value
c--- 1 abcdef01 01efcdab abcdef01
c--- 2 23456789 89674523 23456789
c--- function swbyt2 example
integer*2 src(4)
data src/Z'abcd',Z'ef01',Z'2345',Z'6789'/
c--- if applicable, flip the 4 elements of the array 'src'
c--- into network-byte ordering.
call swbyt2 (src, 4)
c--- Because swbyt2 is a machine-dependent operation the
c--- outcome of this call will vary. On big-endian machines,
c--- swbyt2 will not modify the values in the buffer 'src'.
c--- On little-endian machines it will.
c--- big-endian little-endian
c--- src() input value input value output value
c--- 1 abcd cdab abcd
c--- 2 ef01 01ef ef01
c--- 3 2345 4523 2345
c--- 4 6789 8967 6789
|
Copying
bytes
The McIDAS-X
library contains several functions for copying bytes. Some are simple copy
routines, while others provide for more complicated byte moving operations.
movb and movc
The movb and movc functions
copy a specified number of bytes from one buffer to another. The only difference
between the two is that movb only lets
you specify a destination buffer offset, while movc also
lets you specify an offset from the source buffer.
c--- function movb example
integer src(4)
integer dest(4)
data src/Z'abcdef01',Z'23456789',Z'fedcba98',Z'09080706'/
call zeros (dest, (4 * 4))
c--- copy 15 bytes from the array 'src' into the array 'dest'
c--- beginning at byte 1.
call movb (15, src, dest, 1)
c--- The resulting value in 'dest' will be:
c--- dest() hex
c--- 1 00abcdef
c--- 2 01234567
c--- 3 89fedcba
c--- 4 98090807
c--- function movc example
integer src(4)
integer dest(4)
data src/Z'abcdef01',Z'23456789',Z'fedcba98',Z'09080706'/
call zeros (dest, (4 * 4))
c--- copy 14 bytes from the array 'src' beginning at byte 5
c--- into the array 'dest' beginning at byte 2.
call movc (14, src, 5, dest, 2)
c--- The resulting value in 'dest' will be:
c--- dest() hex
c--- 1 00004567
c--- 2 89fedcba
c--- 3 98090807
c--- 4 06050403
|
movcw
The byte
copying function movcw lets you move a
character string into an integer buffer. This function doesn't convert the
value stored in a string to its integer representation. It merely moves the
bytes into an integer buffer.
Before using
this function, verify that the destination buffer is as least as large as
the source string, as movcw will move the
entire source string to the destination address without protecting against
buffer overflow.
c-- function movcw example
integer dest(3)
character*12 cvar12
call zeros (dest, (4 * 3))
cvar12 = 'June Cleaver'
call movcw (cvar12, dest)
c--- The resulting elements of the array 'dest' will be:
c--- dest() hex string
c--- 1 4a756e65 June
c--- 2 20436c65 Cle
c--- 3 61766572 aver
|
movblk
and movpix
Use
the byte-copying functions movblk and movpix for
complicated byte copying operations. These functions let you specify the
following:
- Segment
sizes to copy
- Number
of bytes to skip between source bytes
- Number
of bytes to skip between destination bytes
Both the movblk and movpix functions
let you copy bytes from one buffer to another with incremental offsets for
both the source and destination buffers. However, the movblk function
has an additional feature that lets you specify the length of each source
element to move. The movpix function has
a fixed, source-byte length of one and includes parameters for sampling bytes
and moving a buffer in reverse order.
The movblk function
is shown in the sample code below.
c--- function movblk example
integer src(16)
integer dest(32)
data src/Z'abcdef01',Z'23456789',Z'fedcba98',Z'09080706',
Z'05040302',Z'010a0b0c',Z'0d0e0f11',Z'22334455',
Z'66778899',Z'aabbccdd',Z'eeff1213',Z'14151617',
Z'18191a1b',Z'1c1d1e1f',Z'21232425',Z'26272829'/
call zeros (dest, (4 * 32))
c--- copy 4 elements that are 3 bytes long beginning at byte 1
c--- in 'src' into 'dest' beginning at byte 6. The increment
c--- between elements in the source buffer is 2 bytes, the
c--- increment between bytes in the destination buffer is
c--- 7 bytes.
call movblk (4, 3, src, 1, 2, dest, 6, 7)
c--- The resulting elements of the array 'dest' will be:
c--- dest() hex
c--- 1 00000000
c--- 2 0000cdef
c--- 3 01000000
c--- 4 00012345
c--- 5 00000000
c--- 6 45678900
c--- 7 00000089
c--- 8 fedc0000
|
The movpix function
is shown in the sample code below.
c--- function movpix example
integer src(16)
integer dest(32)
data src/Z'abcdef01',Z'23456789',Z'fedcba98',Z'09080706',
Z'05040302',Z'010a0b0c',Z'0d0e0f11',Z'22334455',
Z'66778899',Z'aabbccdd',Z'eeff1213',Z'14151617',
Z'18191a1b',Z'1c1d1e1f',Z'21232425',Z'26272829'/
call zeros (dest, (4 * 32))
c--- copy 5 elements beginning at byte 1 in 'src' into 'dest'
c--- beginning at byte 6. the increment between elements in
c--- the source buffer is 2 bytes, the increment between bytes
c--- in the destination buffer is 7 bytes.
call movpix (5, src, 1, 2, dest, 6, 7)
c--- The resulting elements of the array 'dest' will be:
c--- dest() hex
c--- 1 00000000
c--- 2 0000cd00
c--- 3 00000000
c--- 4 00010000
c--- 5 00000000
c--- 6 45000000
c--- 7 00000089
c--- 8 00000000
c--- 9 0000dc00
|
Converting
byte values
The mpixtb function
converts the contents of a buffer to new values based on a lookup table included
in the calling sequence. Simultaneously, it optionally converts the 1-, 2-
or 4-byte data to a different length. This function is used in satellite
calibration routines when a lookup table is generated to convert data from
one physical quantity to another, such as raw values to temperature. The
valid length conversions are 1, 2 or 4 bytes.
c--- function mpixtb example
integer src(16)
integer lookup(16)
data src Z'abcdef01',Z'23456789',Z'fedcba98',Z'09080706',
Z'05040302',Z'010a0b0c',Z'0d0e0f11',Z'22334455',
Z'66778899',Z'aabbccdd',Z'eeff1213',Z'14151617',
Z'18191a1b',Z'1c1d1e1f',Z'21232425',Z'26272829'/
data lookup/15, 14, 13, 12, 11, 10, 9, 8,
0, 1, 2, 3, 4, 5, 6, 7/
c--- convert 8 1-byte elements beginning at src array element 4
c--- into 2-byte elements that have been modified by the lookup
c--- table.
call mpixtb (8, 1, 2, src(4), lookup)
c--- The elements of the array 'src' will be:
c--- original new
c--- value hex value hex
c--- 09080706 00010000
c--- 05040302 00080009
c--- 010a0b0c 000a000b
c--- 0d0e0f11 000c000d
|
The mpixel function
expands and packs the data values in place. If the source of the data is
one byte, but the application expects it as four bytes, mpixel converts
the data without needing an additional buffer.
Moving
byte streams
The literal
conversion functions alit, dlit and lit move
the byte contents of character strings to the basic Fortran variable types.
c--- functions alit, clit, dlit and lit examples
character*4 cvar4
character*8 cvar8
character*4 cval
integer int_dest
double precision dbl_dest
real rel_dest
cvar4 = 'FRED'
cvar8 = '& GINGER'
rel_dest = alit (cvar4)
int_dest = lit (cvar4)
dbl_dest = dlit (cvar8)
cval = clit (int_dest)
|
The clit function
moves the contents of an integer variable to a 4-character variable. These
routines do not convert the string to its integer representation. They merely
move the byte stream into the new variable. The resulting value may not even
be a valid representation on the machine.
Occasionally,
you may need to move a byte stream into whole or half-word integer variables
and back into a byte stream. You can use the crack, pack and pack2 functions
for this purpose, as shown in the sample code below.
integer src(2)
integer dest(8)
data src /Z''abcdef01',Z'23456789'/
c--- function crack example
call zeros (dest, (4 * 8))
call crack (7, src, dest)
c--- The resulting elements of the array ''dest' will be:
c--- dest() hex
c--- 1 000000ab
c--- 2 000000cd
c--- 3 000000ef
c--- 4 00000001
c--- 5 00000023
c--- 6 00000045
c--- 7 00000067
c--- function pack example
integer src(4)
integer val
data src/Z'010000cd',Z'020000ef',Z'03000001',Z'04000023'/
val = 0
call pack(4, src(2), val)
c--- The resulting value in ''val' will be:
c--- hex
c--- cdef0123
c--- function pack2 example
integer*2 src(4)
integer val
data src /Z'0f0e',Z'0d0c',Z'0b0a',Z'0908'/
val = 0
call pack2 (4, src, val)
c--- The resulting value in 'val' will be:
c--- hex
c--- 0e0c0a08
|
Character
string manipulation
This
section describes the primary interfaces that you will use with character strings
in McIDAS-X. These character-string functions were developed to do the following:
- Provide better
error codes than those available in the standard language libraries
- Accommodate
a McIDAS-X-specific syntax for some commonly used parameters unknown to the
standard language libraries
- Control
differences in the way that the C and Fortran languages treat character strings
This
section contains some terms that may be unfamiliar to you. They are defined
below.
- Blank-padded describes
the practice of replacing unused characters at the end of a string with space
characters.
- Double-precision usually
describes a two-word storage representation for floating-point numbers.
- Whitespace is
a subset of the ASCII (American Standard Code for Information Interchange)
character set that includes space, end-of-line, vertical tab, horizontal
tab and form-feed characters.
- Null-terminated describes
the practice of placing a zero (ASCII NULL character) at the end of a character
string; this is the standard representation in the C language.
The string
manipulation functions are listed alphabetically in the table below with a
brief description.
C function |
Fortran function |
Description |
fsalloc |
not
available |
copies
the contents of a Fortran string to a C string, dynamically allocating
the memory necessary to store the resulting string |
fslen |
not
available |
returns
the logical length of a C string needed to contain a blank-padded Fortran
string |
not
available |
ischar |
indicates
whether a string of four characters contains all printable characters |
not
available |
isdgch |
determines
whether a Fortran string contains all digits, all letters, a mixture
of letters and digits, or other characters |
Mclocase |
mclocase |
converts
uppercase characters in a string to lowercase |
Mcstricmp |
not
available |
performs
a case-independent comparison of two C character strings |
Mcstrnicmp |
not
available |
performs
a case-independent comparison of a specified number of characters in
two C strings |
Mcstrtodbl |
mcstrtodbl |
converts
a character string in decimal point format to a double-precision value |
Mcstrtodhr |
mcstrtodhr |
converts
a character string in time format to a double- precision value |
Mcstrtodll |
mcstrtodll |
converts
a character string in lat/lon format to a double-precision value |
Mcstrtohex |
mcstrtohex |
converts
a character string in hexadecimal to an integer value |
Mcstrtohms |
mcstrtohms |
converts
a character string in time format to its components: hours, minutes,
seconds |
Mcstrtoihr |
mcstrtoihr |
converts
a character string in time format to an integer value in units of hours/minutes/seconds |
Mcstrtoill |
mcstrtoill |
converts
a character string in lat/lon format to an integer value in units of
degrees/minutes/seconds |
Mcstrtoint |
mcstrtoint |
converts
a character string to an integer value |
Mcstrtoiyd |
mcstrtoiyd |
converts
a character string representing a day to an integer representation of
Julian day |
Mcstrtofs |
not
available |
copies
a C character string to a Fortran character string |
Mcupcase |
mcupcase |
converts
lowercase characters in a string to uppercase |
not
available |
nchars |
indicates
the starting and ending character positions (1-based) and length of a
Fortran string |
stralloc |
not
available |
concatenates
a variable number of C character strings into a single string pointer |
These string
manipulation functions are further described below with sample code fragments.
Functions that perform similar tasks are grouped together, based on whether
they convert strings, analyze strings, build strings or serve as string utilities.
|
For
more information about these string manipulation functions, see the online
man pages provided with the McIDAS-X software. |
Converting
string formats to integer values
The Mcstrtoint function
converts a variety of string formats to integer values and returns an error
status value less than zero when the calling routine enters an invalid string.
To get a list of the string formats, enter the command ARGHELP INTEGER from
the McIDAS-X command line.
To convert
a hexadecimal string with Mcstrtoint, prefix
the string with a dollar sign ($). When converting exponential representations
with Mcstrtoint, be aware that it returns
an error status if the string can't be completely represented as an integer.
The sample code below converts several string formats to integer values.
{
char src_string[20];
int val;
int status;
/*
* -- convert the character string '4321' to an integer
*/
(void) strcpy (src_string, "4321");
status = Mcstrtoint (src_string, &val);
/* upon exit, the integer value stored in 'val' will be 4321 */
/*
* -- convert the hexadecimal character string '2f' to an integer
*/
(void) strcpy (src_string, "$2f");
status = Mcstrtoint (src_string, &val);
/* upon exit, the integer value stored in 'val' will be 47 */
/*
* -- convert the exponential character string '234e3' to an integer
*/
(void) strcpy (src_string, "234e3");
status = Mcstrtoint (src_string, &val);
/* upon exit, the integer value stored in 'val' will be 234000 */
/*
* -- convert the exponential character string 2340e-1 to an integer
*/
(void) strcpy (src_string, "2340e-1");
status = Mcstrtoint (src_string, &val);
/* upon exit, the integer value stored in 'val' will be 234 */
/*
* -- convert the exponential character string 2340e-2 to an integer
*/
(void) strcpy (src_string, "2340e-2");
status = Mcstrtoint (src_string, &val);
/*
* this call will return an error because the actual value '23.4'
* cannot be represented as an integer variable
*/
}
|
Converting
string formats to double-precision values
The Mcstrtodbl function
converts a variety of string formats to double- precision values and returns
an error status value less than zero when the calling routine enters an invalid
string. To get a list of the string formats, enter the command ARGHELP DECIMAL
on the McIDAS-X command line. The sample code below shows how to use Mcstrtodbl.
{
char src_string[20];
double val;
int status;
/*
* -- convert the character string '-4321.1' to a double
*/
(void) strcpy (src_string, "-4321.1");
status = Mcstrtodbl (src_string, &val);
/* upon exit, the value stored in 'val' will be -4321.1 */
/*
* -- convert the exponential character string '321.2-e3' to a double
*/
(void) strcpy (src_string, "321.2e-3");
status = Mcstrtodbl (src_string, &val);
/* upon exit, the value stored in 'val' will be .3212 */
}
|
Converting
time and latitude/longitude formats
The
four functions below convert a variety of McIDAS-X time and latitude/longitude
formats to double-precision and integer values.
- Mcstrtodhr returns
time values in units of hours as a double- precision value.
- Mcstrtoihr returns
an integer representation of time in the format hhmmss.
- Mcstrtodll returns
latitude or longitude in double-precision values.
- Mcstrtoill returns
a scaled integer representation of latitude and longitude in the integer
format dddmmss.
To get a
list of the time formats, enter the command ARGHELP TIME on the McIDAS-X
command line. To get a list of the latitude/longitude formats, enter the
command ARGHELP LATLON.
If your input
string for Mcstrtodhr or Mcstrtoihr is
the NULL string or colon (:), the value returned is the current system time.
If you always want the current system time, use the McIDAS-X library function Mcgettime.
The calling
sequence and valid string formats for Mcstrtodll and Mcstrtoill are
identical to Mcstrtodhr and Mcstrtoihr,
except the former will not return the current system time if the NULL string
or colon string are passed as input.
{
char src_string[20];
double dval;
int val;
int status;
/*
* -- convert the string '421.1321' to a time
*/
(void) strcpy (src_string, "421.1321");
status = Mcstrtodhr (src_string, &dval);
status = Mcstrtoihr (src_string, &val);
/*
* upon exit, 'dval' will contain 421.321 and 'val' will contain
* 4210756
*/
/*
* -- convert the string '21:32:12' to a time
*/
(void) strcpy (src_string, "21:32:12");
status = Mcstrtodhr (src_string, &dval);
status = Mcstrtoihr (src_string, &val);
/*
* upon exit, 'dval' will contain 21.536 and 'val' will contain 213212
*/
/*
* -- get current system time by entering the special character ":"
*/
(void) strcpy (src_string, ":");
status = Mcstrtodhr (src_string, &dval);
status = Mcstrtoihr (src_string, &val);
/*
* upon exit, 'dval' and 'val' will contain the current system time
* in their respective formats
*/
}
|
Converting
time to hours, minutes, seconds
The Mcstrtohms function
converts a character string of the format hh:mm:ss into
its components. It returns the current time if the input string is the NULL
string or colon (:) and returns an error status value less than zero when
the calling routine enters an invalid string. To list the valid time formats,
enter the command ARGHELP TIME on the McIDAS-X command line.
The sample
code below shows how to use Mcstrtohms.
{
int hour, minute, sec;
int status;
char src_string[20];
/*
* -- convert the string '21:32:12' to its components; hours,
* minutes and seconds
*/
(void) strcpy (src_string, "21:32:12");
status = Mcstrtohms (src_string, &hour, &minute, &sec);
/*
* upon exit, hour = 21, minute = 32 and sec = 12
*/
}
|
Converting
a date in string format to a Julian day
The Mcstrtoiyd function
converts a character string for a given day to a Julian day with integer
value representation.
The
format is ccyyddd, where:
- cc is
the century
- yy is
the year in the century
- ddd is
the day number for the year, 1-based
It returns
the current Julian day if your input string is the NULL string or slash (/)
and returns an error status value less than zero when the calling routine
enters an invalid string.
If your entered
string does not include the century, the current century is assumed. If you
always want the current system day, use the McIDAS-X library function Mcgetday.
To list the
valid date formats, enter the command ARGHELP DATE on the McIDAS-X command
line.
The sample
code below shows the use of the Mcstrtoiyd function.
{
int day;
int status;
char src_string[20];
/*
* -- convert the string "03-APR-1995" to a Julian day
*/
(void) strcpy (src_string, "03-APR-1995");
status = Mcstrtoiyd (src_string, &day);
/*
* upon exit, 'day' will contain 1995093
*/
/*
* -- convert the string "96/04/13" to a Julian day
*/
(void) strcpy (src_string, "96/04/13");
status = Mcstrtoiyd (src_string, &day);
/*
* upon exit, 'day' will contain 1996104, assuming you are
* currently in the 1900s
*/
/*
* -- convert the string "1995366" to a Julian day
*/
(void) strcpy (src_string, "1995366");
status = Mcstrtoiyd (src_string, &day);
/*
* status will be less than 0 because there was no day 366
* in 1995
*/
}
|
|
For
more information about dates and time, see the section Day
and time in this chapter. |
Converting
a C character string to Fortran
Mcstrtofs converts a C character string to a Fortran character string. If the source
string is shorter than the destination string, the remaining bytes in the
destination string are filled with the ASCII space character. If the C string
is longer than the Fortran string, it is truncated in the Fortran string.
character*24 fullname
call getname (fullname)
call sdest (fullname,0)
:
:
|
void getname_ (char *fname, FsLen len_name)
{
char string[72];
int status;
(void) strcpy (string, "Ted Williams");
status = Mcstrtofs (fname, string, len_name);
return;
}
|
Converting
a Fortran character string to C
The fsalloc function,
which is called from a C routine, performs these tasks:
- Determines
the amount of memory required to store the string
- Allocates
that amount of memory
- Converts
the Fortran character string to a C character string
- Assigns
the new string to a character pointer variable
The fsalloc function
does not allocate memory to store whitespace bytes at the end of the original
source string. Because this function dynamically allocates memory, the calling
program is responsible for freeing up the memory when finished with it. If
allocation fails, the returned value is (char *) NULL.
Calling routines should always test for this condition.
The code
fragment below shows you how to use fsalloc.
character*24 fullname
data fullname/'Joe Dimaggio'/
call printhof (fullname)
:
:
void printhof_ (char *fname, FsLen len_name)
{
char *cname;
cname = fsalloc (fname, len_name);
/*
* if the memory allocation is successful, 'cname' will point
* to 13 bytes of memory that have been filled with the
* characters 'Joe Dimaggio' for the first 12 bytes and the
* NULL byte for the final value. note that it will not
* allocate the full 24 bytes of memory for this example
* because the final 12 bytes of the original character
* string are whitespace characters.
*/
if (cname != (char *) NULL)
{
Mcprintf ("Hall of Famer: %s\n", cname);
free (cname);
}
return;
}
|
Determining
the contents of a string
The ischar function
tells the calling routine if a string of four characters is from the printable
ASCII character set, including the space character. The isdgch function
tells the calling routine if a string of characters contains all digits,
all letters, a mixture of digits and letters, or other characters. The sample
code below shows the use of both functions.
character*4 cvar4
character*12 cvar12
integer status
cvar4 = 'AbcD'
status = ischar (cvar4)
c--- upon return, 'status' will contain the value 1 indicating
c--- that all 4 characters are printable.
cvar12 = '3214as231G'
status = isdgch (cvar12)
c--- upon return,'status' will contain the value 0 indicating
c--- that the string contains a mixture of letters and digits.
|
Determining
the number of characters in a string
The nchars function
returns the location of the first and last non-blank characters (1-based)
along with the length of the printable characters in a string. This function
does not consider space characters printable when determining the values
to return for starting and ending positions.
character*12 cvar12
integer status
integer begchr
integer endchr
integer length
cvar12 = ' Ty Cobb'
length = nchars (cvar12, begchr, endchr)
c--- upon exit, 'length' contains the value 7, 'begchr'
c--- contains the value 3, and 'endchr' contains the value 9.
|
Comparing
two strings
Mcstricmp performs
a case-insensitive string comparison between two entire strings. Mcstrnicmp performs
a similar comparison, but only for the number of bytes specified by the calling
routine. Both functions return a value less than zero if the lexical value
of the first string is less than that of the second string. They return a
value greater than zero if the lexical value in the first string is greater
than that of the second string. They return the value zero if the strings
are identical.
{
char string1[20];
char string2[20];
int status;
(void) strcpy (string1, "BOB GIBSON");
(void) strcpy (string2, "bob feller");
/* compare the contents of 'string1' and `string2' */
status = Mcstricmp (string1, string2);
/*
* because the string "bob feller" occurs earlier in an
* alphabetic listing than "BOB GIBSON" the value of
* 'status' would be greater than 0.
*/
/*
* compare the first 3 characters of the variables
* 'string1' and 'string2'
*/
status = Mcstrnicmp (string1, string2, 3);
/*
* because the first 3 characters of both strings contain
* the word "Bob", the value of 'status' would be 0.
*/
}
|
Concatenating
a series of strings
The stralloc function
has a variable number of calling parameters that concatenate a series of
strings into a new string. The final parameter in the calling sequence must
be the NULL pointer.
This function
dynamically allocates memory for the resulting string. The calling function
must free that block of memory when it is finished.
{
char t_string[20];
char *string1;
(void) strcpy (t_string, "WISCONSIN");
string1 = stralloc ("ST", "=", t_string, (char *) NULL);
/*
* upon successful exit the 'string1' would point to a block
* of memory that is 13 bytes long and contain the following
* string: "ST=WISCONSIN"
*/
if (string1 != (char *) NULL)
{
Mcprintf ("%s\n", string1);
free (string1);
}
string1 = stralloc ("CO=", "US", " ", "MX", " ", "UK", (char *) NULL);
/*
* upon successful exit the 'string1' would point to a block
* of memory that is 12 bytes long and contain the following string:
* "CO=US MX UK"
*/
if (string1 != (char *) NULL)
{
Mcprintf ("%s\n", string1);
free (string1);
}
return;
}
|
Converting
lowercase and uppercase characters
The Mclocase and Mcupcase functions
convert the letters of a character string to all lowercase or uppercase respectively,
as shown in the sample code below. Non-alphabetic characters in the string
are unmodified.
{
char name[20];
(void) strcpy (name, "Hank Aaron!!");
/* convert the contents of the character array 'name'
* to lowercase
*/
Mclocase (name);
/*
* upon exit, the content of the character array 'name'
* will be: "hank aaron!!"
*/
/* convert the contents of the character array 'name'
* to uppercase
*/
Mcupcase (name);
/*
* upon exit, the content of the character array 'name'
* will be: "HANK AARON!!"
*/
}
|
Day
and time
Day and Time
conversion utilities consist of the follwing:
All McIDAS-X
applications use the Julian day format. To correctly represent both the twentieth
and twenty-first centuries, the McIDAS-X library provides Julian day manipulation
routines using the format ccyyddd where cc represents
the century, yy is the year of the century and ddd is
the day of the year, with January 1 being day one. For example, 17 January
1997 is represented as 1997017.
In addition,
there is one more variant of the yyyddd format. This
format represents the julian day of the year 1900+yyy. As examples, 99119 is
day 119 of the year 1999, and 102231 is day 231 of the year 2002. This format
is used in many McIDAS-X data structures for internal storage, but is usually
coverted to ccyyddd for user listings.
Some of the
functions described in this section still expect the older Julian day format, yyddd.
However, they will be replaced with the new format.
The time utilities
described in this section use the integer representation hhmmss for
time and return the time in UTC, Coordinated Universal Time.
Below is an
alphabetical listing of the day and time functions available in the McIDAS-X
library, along with a short description.
C function |
Fortran function |
Description |
Mccydok |
mccydok |
verifies
that a Julian day in the form ccyyddd is correct |
Mccydtodmy |
mccydtodmy |
converts
a Julian day in the form ccyyddd to day, month and year |
Mccydtodow |
mccydtodow |
converts
date to day of the week |
Mccydtoiyd |
mccydtoiyd |
converts
date in ccyyddd format to yyyddd |
Mccydtostr |
mccydtostr |
converts
the Julian day in the form ccyyddd to a variety of character string formats |
Mccydtoyd |
mccydtoyd |
converts
a 7-digit Julian day to 5 digits |
Mcdaytimetosec |
mcdaytimetosec |
converts
a Julian day in the form ccyyddd and the time of day in the form hhmmss
to seconds since 1 January 1970 at 00 UTC |
Mcdhrtoihr |
mcdhrtoihr |
converts
hours stored in double precision to hours stored in an integer of the
form hhmmss |
Mcdmytocyd |
mcdmytocyd |
converts
day, month and year to a Julian day in the form ccyyddd |
Mcgetday |
mcgetday |
gets
the current system Julian day in the form ccyyddd |
Mcgetdaytime |
mcgetdaytime |
gets
the current Julian day in the form ccyyddd and the current time of day
in the form hhmmss |
Mcgettim |
gettime |
gets
the current time of day in the form hhmmss |
Mchmsok |
mchmsok |
verifies
that a time value in the form hhmmss is correct |
Mchmstoihr |
not
available |
converts
hours, minutes and seconds to hhmmss format |
Mcincday |
mcincday |
increments/decrements
a Julian day value |
Mcinctime |
mcinctime |
increments/decrements
a Julian day and time value |
Mcisleap |
mcisleap |
checks
to see if the four-digit field represents a leap year |
Mcistimeofday |
mcistimeofday |
verifies
the value given to be a valid time of day |
Mciydtocyd |
mciydtocyd |
converts
date in yyyddd format to ccyyddd |
Mcsectodaytime |
mcsectodaytime |
converts
seconds since 1 January 1970 to a Julian day in the form ccyyddd and
a time in the form hhmmss |
Mcydtocyd |
mcydtocyd |
converts
a 5-digit Julian day to 7 digits |
These functions
are further defined below along with examples of sample code. The more commonly
used functions are described first.
|
For
more information on these day and time functions, see the online man
pages provided with the McIDAS-X software. |
Retrieving
the current system day and time
The
McIDAS-X library contains these three current day/time functions:
- Mcgetday retrieves
the current system Julian day.
- Mcgettime returns
the current system time in UTC.
- Mcgetdaytime retrieves
both.
If you write
applications that need both current day and time, use Mcgetdaytime.
This function doesn't have the potential timing problem associated with retrieving
the information in separate calls. This timing problem surfaces just before
the Julian day changes. For example, if you call Mcgetday at
23:59:59 on a particular day but don't call Mcgettime until
two seconds later, your day and time won't match because your time will read
00:00:01.
The sample
code below shows the use of all three functions.
{
int CurrentDay;
int CurrentTime;
int status;
/* get current system day and time. this is the undesirable
* manner
*/
status = Mcgetday (&CurrentDay);
status = Mcgettime (&CurrentTime);
/*
* CurrentDay will contain the current system day in the form
* ccyyddd. CurrentTime will contain the current time in the
* form hhmmss
*/
/* get current system day and time. this is the preferred
* manner
*/
status = Mcgetdaytime (&CurrentDay, &CurrentTime);
}
|
Converting
a 5-digit Julian day to 7-digit, and vice versa
You
can use the Mccydtoyd and Mcydtocyd functions
to transition your code from the previous 5-digit Julian day format, yyddd,
to the new 7-digit format, ccyyddd, and vice versa.
- Mccydtoyd converts
the 7-digit Julian day format to the 5-digit representation.
- Mcydtocyd converts
the 5-digit Julian day format to the 7-digit version.
The Mcydtocyd function
assumes that if the year of the century (yy) in
the 5-digit format is less than or equal to 69, it is the 21st century; if
the year of the century is greater than or equal to 70, it assumes the 20th
century.
See the sample
code below.
{
int status;
int new_day;
/* convert the day 1996017 to the 5 digit form of the Julian day */
status = Mccydtoyd (1996017, &new_day);
/* if successful, the contents of new_day will be 96017 */
/* convert the day 96100 to the 7 digit form of the Julian day */
status = Mcydtocyd (96100, &new_day);
/* if successful, the contents of new_day will be 1996100 */
/* convert the day 11100 to the 7 digit form of the Julian day */
status = Mcydtocyd (11100, &new_day);
/* if successful, the contents of new_day will be 2011100 */
}
|
Converting
to and from dates in IYD and CCYYDDD format
When servers
present grid image or point data, the date fields are usually passed in a yyyddd format,
where yyy represents years since 1900 and ddd represents
the day count from the beginning of the year (1-based).
When the
data is presented, the dates are in ccyyddd format,
where cc is the century field, yy is
the year of the century field and ddd is the julian
day of the year.
Two functions
are used to convert the data: mciydtocyd,
which converts from the yyyddd format to the ccyyddd format,
and mccydtoiyd,
which converts from the ccyyddd format to the yyyddd format.
The sample
code below, from m0ptrdhdr, shows how to
use Mciydtocyd.
c
c--- modify schema and creation date fields
c
istat=mciydtocyd(header(3),temp_date)
header(3)=temp_date
istat=mciydtocyd(header(26),temp_date)
header(26)=temp_date
|
The sample
code below, from m0makara, shows how to
use mccydtoiyd.
C --- Get, convert current ccyyddd to yyyddd
C --- Store time directly.
ival=mcgetdaytime(century_date,aradir(18))
if(ival.lt.0) then
call edest('Unable to write creation date',0)
m0makara=-3
endif
ival = mccydtoiyd(century_date,adir_date)
aradir(17) = adir_date
|
Converting
a Julian day and time to seconds, and vice versa
Mcdaytimetosec and Mcsectodaytime convert
Julian day and time to absolute times based from 1 January 1970 at 00 UTC,
and vice versa. This standard is different from the McIDAS-X functions sksecs and skhms,
which use 1 January 1972 as the base.
#include <time.h
{
int day;
int time;
time_t seconds;
int status;
/*
* get the number of seconds since 1 January 1970 for Julian
* day 1997017 at 12:30UTC
*/
day = 1997017;
time = 123000;
status = Mcdaytimetosec (day, time, &seconds);
/* upon successful exit, the value of 'seconds' will be
* 853584200
*/
/*
* convert 853584200 seconds since 1 January 1970 to a
* Julian day and time
*/
status = Mcsectodaytime (seconds, &day, &time);
/*
* upon successful exit, the value of 'day' will be
* 1997017 and the value of 'time' will be 123000
*/
}
|
Converting
a Julian day to day/month/year, and vice versa
Mccydtodmy converts
a Julian day to day, month and year, including the century. The month number
returned is 1-based, meaning January is 1. Mcdmytocyd converts
a day, month, year combination to a Julian day. Examples of both functions
are shown in the code fragment below.
{
int dayofmonth;
int month;
int year;
int day;
int status;
/* convert the day 9 May 1996 to a Julian day */
dayofmonth = 9;
month = 5;
year = 1996;
status = Mcdmytocyd (dayofmonth, month, year, &day);
/* upon successful completion 'day' will contain the
* value 1996130
*/
/* convert the day 29 February 1995 to a Julian day */
dayofmonth = 29;
month = 2;
year = 1995;
status = Mcdmytocyd (dayofmonth, month, year, &day);
/* this conversion will fail because there was no
* 29 February 1995
*/
/* convert the Julian day 1996060 to a day, month and year */
day = 1996060;
status = Mccydtodmy (day, &dayofmonth, &month, &year);
/*
* upon successful completion 'dayofmonth' will contain 29,
* 'month' will contain 2 and 'year' will contain 1996
*/
}
|
Converting
a Julian day to a character string
Mccydtostr converts
a Julian day to a variety of character strings representing the date, as
shown in the code sample below.
{
int status;
char *day_string;
/*
* convert the Julian day 1996017 to a character string of the
* form nn mmm, ccyy
*/
status = Mccydtostr (1996017, 4, &day_string);
/*
* upon successful completion, the contents of the variable
* day_string will be '17 Jan, 1996'. For a complete listing
* of the output formats available, see the McIDAS API
* Reference Manual.
*/
}
|
Determining
if a year is a leap year
You can use Mcisleap to
determine if a four-digit year is a leap year. See the sample code below.
iam=-1
c --- get the current day
i=mcgetday(kurrent_day)
kurrent_year=kurrent_day/1000
iam=mcisleap(kurrent_year)
if(iam.eq.0) then
call sdest('Current year is not a leap year',0)
elseif(iam.eq.1) then
call sdest('Current year is a leap year',0)
endif
|
Incrementing
day and time
When writing
applications for real-time data, you may need to increment day and time parameters
to locate data for an application. However, when you work with the beginning
or ending day of a particular year, you can't just add a one to
a Julian day and expect the correct resulting date. Use the Mcincday function
to increment and decrement a Julian day by days. Use the Mcinctime function
to increment and decrement a day/time pair by a time increment. A positive
increment value results in a future time; negative numbers result in a past
time.
{
int new_day;
int new_time;
int status;
/* increment the Julian day 1996364 by 3 days */
status = Mcincday (1996364, 3, &new_day);
/*
* upon successful completion, 'new_day' will contain
* the value 1997001
*/
/* decrement the day/time pair 1996002/12UTC by 78 hours */
status = Mcinctime (1996002, 120000, -780000, &new_day, &new_time);
/*
* upon successful completion, 'new_day' will contain the
* value 1995364 and 'new_time' will contain the value 60000
*/
}
|
Latitude
and longitude
The
McIDAS-X library contains two utilities for converting latitude and longitude
values:
- flalo converts
an integer representation of latitude or longitude
in the format dddmmss to a single-precision representation,
in degrees.
- ilalo converts
a single-precision latitude or longitude to a scaled- integer value in the
format dddmmss.
Because workstations
can represent floating-point values differently, most data requiring fractional
representation, such as latitude and longitude, is stored as scaled integers.
While scaled integers are adequate for data storage, performing mathematical
operations on these values is difficult.
Use the flalo function
to convert the scaled-integer representation of latitude and longitude into
single-precision floating point numbers. Use the ilalo function
to convert single-precision floating-point values to scaled-integer representation.
The sample code below demonstrates the latitude and longitude conversion functions.
integer lat
real flat
c--- convert 59 degrees 30 minutes to a single precision
c--- floating point value
lat = 593000
flat = flalo (lat)
c--- upon successful completion, 'flat' contains the value 59.5
c--- convert the latitude value 45.75 to a scaled integer value
flat = 45.75
lat = ilalo (flat)
c--- upon successful completion, 'lat' contains the value 454500
|
|
For
more information about these conversion functions, see the online man
pages provided with the McIDAS-X software. |
Physical
units
The
McIDAS-X library contains two utilities for converting physical units:
- mcucvtd converts
a list of double-precision values from one physical unit to a different physical
unit.
- mcucvtr converts
a list of single-precision values from one physical unit to a different physical
unit.
Unit conversion
is a integral part of any user application because data is often stored in
units that a user won't typically display. The mcucvtd and mcucvtr functions
can convert the physical units shown in the table below; all McIDAS-X core
datasets use this standard.
Attribute |
Valid units |
Interface representation |
length |
meters
kilometers
decameters
centimeters
millimeters
miles
nautical miles
yards
feet
inches
degrees of latitude |
M
KM
DM
CM
MM
MI
NMI
YD
FT
IN
DEGL |
speed |
miles
per hour
knots
meters per second
feet per second
kilometers per hour |
MPH
KT or KTS
MPS
FPS
KPH |
temperature |
Kelvin
Fahrenheit
Celsius |
K
F
C |
pressure |
millibars
inches of Mercury
pascals
hectopascals |
MB
INHG
PA
HPA |
time |
hours
minutes
seconds
days
years |
HR
MIN
SEC
DAY
YR |
weight |
grams
kilograms
pounds
ounces
tons |
G
KG
LB
OZ
TON |
The code segment
below demonstrates these unit conversion routines.
integer numval
character*4 inunit
character*4 outunit
integer status
double precision outval
numval = 1
c--- Convert 50 degrees fahrenheit to celsius
inunit = 'F'
outunit = 'C'
status = mcucvtd (numval, inunit, 50.d0, outunit, outval, 0)
c--- Upon successful completion, 'outval' will contain the
c--- value 10.0.
c--- Convert 50 degrees fahrenheit to feet
outunit = 'FT'
status = mcucvtd (numval, inunit, 50.d0, outunit, outval, 0)
c--- the value of 'status' will be -1 because you cannot
c--- convert degrees fahrenheit to feet.
|
|
For
more information about these conversion functions, see the online man
pages provided with the McIDAS-X software. |
[Search Manual]
[Table of Contents] [Go
to Previous] [Go
to Next]