String to Number Conversions

I l @ ve RuBoard

String to Number Conversions

Numbers can be stored either as strings or in numeric form. Storing a number as a string means storing the digit characters . For instance, the number 213 can be stored in a character string array as the digits `2' , `1' , `3' , `\0' . Storing 213 in numeric form means storing it as, say, an int .

C requires numeric forms for numeric operations, such as addition and comparison, but displaying numbers on your screen requires a string form because a screen displays characters. The printf() and sprintf() functions, through their %d and other specifiers, convert numeric forms to string forms and vice versa. C also has functions whose sole purpose is to convert string forms to numeric forms.

Suppose, for example, you want a program to use a numeric command-line argument. Unfortunately, command-line arguments are read as strings. Therefore, to use the numeric value, you must first convert the string to a number. If the number is an integer, you can use the atoi() function (for al phanumeric to i nteger). It takes a string as an argument and returns the corresponding integer value. Listing 11.28 shows a sample use.

Listing 11.28 The hello.c program.
 /* hello.c -- converts command-line argument to number */ #include <stdio.h> #include <stdlib.h> int main(int argc, char *argv[]) {   int i, times;   if (argc < 2  (times = atoi(argv[1])) < 1)        printf("Usage: %s positive-number\n", argv[0]);   else        for (i = 0; i < times; i++)             puts("Hello, good looking!");   return 0; } 

Here's a sample run:

 %  hello 3  Hello, good looking! Hello, good looking! Hello, good looking! 

The % is a UNIX prompt. The command-line argument of 3 was stored as the string "3\0" . The atoi() function converted this string to the integer value 3 , which was assigned to times . This then determined the number of for loop cycles executed.

If you run the program without a command-line argument, the argc < 2 test aborts the program and prints a usage message. The same thing happens if times is 0 or negative. C's order-of-evaluation rule for logical operators guarantees that if argc < 2 , then atoi(argv[1]) is not evaluated.

The atoi() function still works if the string only begins with an integer. In that case, it converts characters until it encounters something that is not part of an integer. For example, atoi("42regular") returns the integer 42 . What if the command line is something like hello what? On the implementations we've used, the atoi() function returns a value of if its argument is not recognizable as a number. However, the ANSI standard does not require that behavior.

We include the stdlib.h header because, under ANSI C, it contains the function declaration for atoi() . That header file also includes declarations for atof() and atol() . The atof() function converts a string to a type double value, and the atol() function converts a string to a type long value. They work analogously to atoi() , so they are type double and long , respectively.

ANSI C has supplied more sophisticated versions of these functions: strtol () converts a string to a long , stsroul() converts a string to an unsigned long , and strtod () converts a string to double . The more sophisticated aspect is that the functions identify and report the first character in the string that is not part of a number. Also, strtol() and strtoul () allow you to specify a number base.

Let's look at an example involving strtol(). Its prototype is this:

 long strtol(const char *nptr, char **endptr, int base); 

Here, nptr is a pointer to the string you want to convert, endptr is the address of a pointer that gets set to the address of the character terminating the input number, and base is the number base the number is written in. An example, given in Listing 11.29, makes this clearer.

Listing 11.29 The strcnvt.c program.
 /* strcnvt.c -- try strtol()  */ #include <stdio.h> #include <stdlib.h> int main() {     char number[30];     char * end;     long value;     puts("Enter a number (empty line to quit):");     while(gets(number) && number[0] != ` 
  /* strcnvt.c -- try strtol() */ #include <stdio.h> #include <stdlib.h> int main() { char number[30]; char * end; long value; puts("Enter a number (empty line to quit):"); while(gets(number) && number[0] != `\0') { value = strtol(number, &end, 10); printf("value: %ld, stopped at %s (%d)\n", value, end, *end); value = strtol(number, &end, 16); printf("value: %ld, stopped at %s (%d)\n", value, end, *end); puts("Next number:"); } puts("Bye!\n"); return 0; }  
') { value = strtol(number, &end, 10); printf("value: %ld, stopped at %s (%d)\n", value, end, *end); value = strtol(number, &end, 16); printf("value: %ld, stopped at %s (%d)\n", value, end, *end); puts("Next number:"); } puts("Bye!\n"); return 0; }

Here is some sample output:

 Enter a number (empty line to quit):  10  value: 10, stopped at  (0) value: 16, stopped at  (0) Next number:  10atom  value: 10, stopped at atom (97) value: 266, stopped at tom (116) Next number: Bye! 

First, note that the string "10" is converted to the number 10 when base is 10 and to 16 when base is 16. Also note that if end points to a character, then *end is a character. Therefore, the first conversion ended when the null character was reached, so end pointed to the null character. Printing end displays an empty string, and printing *end with the %d format displays the ASCII code for the null character.

For the second input string (base 10 interpretation), end is given the address of the `a' character. So printing end displays the string "atom", and printing *end displays the ASCII code for the `a' character. When the base is changed to 16, however, the `a' character is recognized as a valid hexadecimal digit, and the function converts the hexadecimal number 10a to 266 , base 10.

The strtol() function goes up to base 36, using the letters through `z' as digits. The strtoul() function does the same, but converts unsigned values. The strtod() function does only base 10, so it uses just two arguments.

Many implementations have itoa() and ftoa() functions for converting integers and floating-point values to strings. However, they are not part of the ANSI C library; use sprintf() , instead, for greater compatibility.

I l @ ve RuBoard


C++ Primer Plus
C Primer Plus (5th Edition)
ISBN: 0672326965
EAN: 2147483647
Year: 2000
Pages: 314
Authors: Stephen Prata

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net