Converting a number to a corresponding string or sequence of characters is a surprisingly common task. Similarly, converting a string of digits and related characters (e.g., '.' or '-') to a number is also a frequent programming task. When the operating system (OS) runs a program, it provides a host environment separating the program from the hardware. Programs exchange data with the OS as C-strings through system calls. The system calls that read from and write to the console only have two arguments: a C-string and the number of characters to transfer. So, the OS exchanges data with the program and the console as C-strings.
Programs are responsible for converting between strings and numbers. Most programming languages provide services, either built into the language or provided as library functions, for converting and formatting numbers. For example, C++ provides the inserter and extractor operators (<< and >>), and a variety of manipulators. Nevertheless, the services ultimately make system calls to the OS, exchanging data only as strings. Subsequent examples demonstrate that it is sometimes convenient for programs to make conversions outside of I/O operations.
| Documentation Prototypes | Example Function Calls |
|---|---|
int atoi(const char* str); |
cout << atoi(s1) << endl;
cout << atoi("123") << endl; |
long atol(const char* str); |
cout << atol(s1) << endl;
cout << atol("123") << endl; |
double atof(const char* str); |
cout << atof(s2) << endl;
cout << atof("3.14159") << endl; |
| Documentation Prototypes | Example Function Calls |
|---|---|
long strtol(const char* index, char** endptr, int base); |
cout << strtol("123", nullptr, 10) << endl;
cout << strtol("0xafcd", nullptr, 16) << endl; |
double strtod(const char* index, char** endptr); |
cout << strtod("3.14159", nullptr) << endl; |
![]() |
![]() |
| (a) | (b) |
#include <iostream>
using namespace std;
int main()
{
char s[] = "123 456 789";
char* end = nullptr;
cout << strtol(s, &end, 10) << endl;
cout << strtol(end, &end, 10) << endl;
cout << strtol(end, &end, 10) << endl;
return 0;
} |
#include <iostream>
using namespace std;
int main()
{
char s[] = "123 456 789";
char* end = s;
while (*end != '\0')
cout << strtol(end, &end, 10) << endl;
return 0;
} |
| (c) | (d) |
char** endptr parameter in the function prototypes above defines a C-string passed by pointer. Adding parentheses clarifies the separate parts: (char*)*. Passing the local pointer variable end by pointer makes it an INOUT argument, saving the function's current processing location in the string. The strtol and strtod functions update the location when they encounter a delimiter.
Strangely, C++ does not include any standard number-to-string functions. (Although more complicated, it can do the conversions with stream objects.) The CRT does have some conversion functions, but the ANSI C++ standard does not included them. Therefore, their support and implementation vary between compilers. You can often find source code for these functions on the Internet, and we'll write a simple version in the cpalnumber example program.
| Documentation Prototypes | Example Function Calls |
|---|---|
char s[25]; | |
char* itoa(int num, char* str, int base); |
itoa(123, s, 10); itoa(0xaf48, s, 16); |
char* _itoa(int num, char* str, int base); |
_itoa(123, s, 10); _itoa(0xaf48, s, 16); |
errno_t _itoa_s(int num, char* str, size_t size, int base); |
_itoa_s(123, s, 25, 10); _itoa_s(0xaf48, s, 25, 16); |