C Function Strtol
## C Library Function - `strtol()`
The `strtol()` function is a standard C library function declared in the `` header. It converts a character string to a long integer (`long int`) representation based on a specified base (radix).
Unlike simpler conversion functions like `atoi()`, `strtol()` provides robust error checking, handles different number bases (from binary to base-36), and reports where the conversion stopped.
---
## Syntax
```c
long int strtol(const char *str, char **endptr, int base);
```
### Parameters
* **`str`**: A pointer to the null-terminated string to be converted.
* **`endptr`**: A pointer to a `char*` object (i.e., a pointer to a pointer). The function sets this pointer to reference the first character in `str` that follows the successfully parsed numeric value. If this parameter is set to `NULL`, it is ignored.
* **`base`**: The radix/base of the number system to use for conversion. It must be an integer between `2` and `36` (inclusive), or the special value `0`.
* **If `base` is between 2 and 36**: The conversion uses the specified base. For bases greater than 10, letters from `a` to `z` (or `A` to `Z`) are used to represent digits from 10 to 35.
* **If `base` is `0`**: The function automatically detects the base from the prefix of the string:
* If the string starts with `0x` or `0X`, it is parsed as **hexadecimal** (base 16).
* If the string starts with `0`, it is parsed as **octal** (base 8).
* Otherwise, it is parsed as **decimal** (base 10).
### Return Value
* **Success**: Returns the converted long integer value.
* **No Conversion**: If no valid digit sequence is found, the function returns `0`. In this case, `endptr` is set to the original `str` pointer (if `endptr` is not `NULL`).
* **Overflow/Underflow**: If the converted value falls outside the representable range of a `long int`, the function returns:
* `LONG_MAX` (on overflow)
* `LONG_MIN` (on underflow)
* Additionally, the global variable `errno` is set to `ERANGE` (defined in ``).
---
## Code Examples
### Example 1: Successful Decimal Conversion
The following example demonstrates converting a clean decimal string `"12345"` into a `long int`.
```c
#include
#include
int main() {
char str[] = "12345";
char *endptr;
long int num;
// Convert string to base-10 long integer
num = strtol(str, &endptr, 10);
// Check if the entire string was successfully converted
if (*endptr != '\0') {
printf("Conversion failed: The input string is not a fully valid integer.\n");
} else {
printf("Conversion successful: %ld\n", num);
}
return 0;
}
```
**Output:**
```text
Conversion successful: 12345
```
---
### Example 2: Handling Partial Conversions and Invalid Characters
If the input string contains non-numeric characters, `strtol()` parses the valid numeric prefix and stops at the first invalid character. `endptr` is updated to point to this character.
```c
#include
#include
int main() {
char str[] = "12ab";
char *endptr;
long int num;
// Convert string to base-10 long integer
num = strtol(str, &endptr, 10);
// If endptr does not point to the null terminator, a partial conversion occurred
if (*endptr != '\0') {
printf("Partial conversion occurred. Converted value: %ld\n", num);
printf("Unconverted part: %s\n", endptr);
} else {
printf("Conversion successful: %ld\n", num);
}
return 0;
}
```
**Output:**
```text
Partial conversion occurred. Converted value: 12
Unconverted part: ab
```
---
### Example 3: Automatic Base Detection (Base = 0)
Setting the `base` parameter to `0` allows `strtol()` to dynamically parse octal, hexadecimal, and decimal strings based on their prefixes.
```c
#include
#include
int main() {
char hex_str[] = "0x1A"; // Hexadecimal
char oct_str[] = "010"; // Octal
char dec_str[] = "100"; // Decimal
char *endptr;
printf("Hex string '0x1A' parsed with base 0: %ld\n", strtol(hex_str, &endptr, 0));
printf("Octal string '010' parsed with base 0: %ld\n", strtol(oct_str, &endptr, 0));
printf("Decimal string '100' parsed with base 0: %ld\n", strtol(dec_str, &endptr, 0));
return 0;
}
```
**Output:**
```text
Hex string '0x1A' parsed with base 0: 26
Octal string '010' parsed with base 0: 8
Decimal string '100' parsed with base 0: 100
```
---
## Key Considerations & Best Practices
1. **Prefer `strtol()` over `atoi()`**:
The `atoi()` function is simpler but does not handle errors or overflow. If `atoi()` fails, its behavior is undefined (or it returns `0` without letting you know if the input was actually `"0"` or invalid). `strtol()` provides robust error detection via `endptr` and `errno`.
2. **Checking for Overflow**:
To safely check for overflow or underflow, clear `errno` before calling `strtol()` and check its value afterward:
```c
#include
// ...
errno = 0;
long val = strtol(str, &endptr, 10);
if ((val == LONG_MAX || val == LONG_MIN) && errno == ERANGE) {
// Handle overflow/underflow error
}
```
3. **Whitespace Handling**:
`strtol()` automatically skips any leading whitespace characters (as identified by `isspace()`) before attempting to parse the number.
YouTip