1 atoi() 函数
1.1 函数原型
#include <stdlib.h> // 必须包含这个头文件
int atoi(const char *str);
1.2 功能说明
atoi() 函数的主要作用是将给定的字符串转换为整数(int 类型)。该函数仅执行基础的字符串到整数的转换操作,不具备错误检测机制。
- 参数:
- str:待转换的 C 字符串,即以 null(\0)结尾的字符数组。
- 返回值:
- 若成功完成字符串到整数的转换,则返回对应的整数值。
- 若无法完成转换,则返回 0。
1.3 转换规则
- 忽略前导空格:在处理字符串时,首先跳过字符串开头所有空白字符,这些空白字符包括空格、制表符(\t)、换行符(\n)等。
- 识别正负号:在跳过前导空格后,若字符串中存在可选的 + 或 - 符号,该符号将决定最终转换得到的整数的正负性。
- 读取数字:从识别出正负号(若存在)之后的位置开始,连续读取数字字符(0 到 9),直到遇到第一个非数字字符为止。
- 停止转换:一旦遇到第一个非数字字符,立即停止解析过程,后续的字符将不再进行处理。
- 返回结果:将解析得到的数字序列转换为 int 类型并返回。
示例转换:
输入字符串 | 返回值 | 说明 |
---|---|---|
"12345" | 12345 | 十进制转换 |
"-6789" | -6789 | 负十进制转换 |
" +42" | 42 | 忽略前导空格和正号 |
"123abc" | 123 | 遇到非数字字符停止 |
"Hello123" | 0 | 无效输入,返回 0 |
"0000000" | 0 | 前导零被忽略 |
1.4 注意事项
- 无法区分 0 和错误:
- 当字符串无法转换为有效的整数时(例如输入为 "Hello123"),atoi() 函数会直接返回 0。
- 这种情况下,无法通过返回值来判断是输入本身就为 0,还是由于输入错误导致无法转换。
- 溢出问题:
- 如果待转换的数值超出了 int 类型的表示范围(例如在 32 位系统中输入 "2147483648",这超出了 int 的最大值 2147483647),atoi() 的行为是未定义的。
- 这可能导致函数返回一个错误的值,或者触发不可预测的行为,如程序崩溃。
- 不推荐用于用户输入:
- 由于 atoi() 函数缺乏错误检测机制,它不适合处理来自不可信来源的输入,如用户输入。
- 在处理用户输入时,应该使用具有错误检测功能的函数,如 strtol(),以便能够正确处理各种错误情况。
- 简单场景适用:
- atoi() 函数仅适用于那些已知格式正确、无需错误检测的简单转换场景。
- 例如,当处理硬编码的字符串或内部数据时,如果确定这些数据始终是有效的整数格式,那么可以使用 atoi() 进行转换。
1.5 示例程序
#include <stdio.h>
#include <stdlib.h> // 必须包含这个头文件才能使用 atoi()
int main()
{
// 示例 1:基本转换
printf("转换结果1: %d\n", atoi("12345")); // 输出: 12345
// 示例 2:带符号的数字
printf("转换结果2: %d\n", atoi("-6789")); // 输出: -6789
// 示例 3:带前导空格和符号
printf("转换结果3: %d\n", atoi(" +42")); // 输出: 42
// 示例 4:部分有效的数字
printf("转换结果4: %d\n", atoi("123abc")); // 输出: 123
// 示例 5:无效输入
printf("转换结果5: %d\n", atoi("Hello123")); // 输出: 0
// 示例 6:全是零
printf("转换结果6: %d\n", atoi("0000000")); // 输出: 0
return 0;
}
程序在 VS Code 中的运行结果如下所示:
2 atol() 函数
2.1 函数原型
#include <stdlib.h> // 必须包含这个头文件
long atol(const char *str);
2.2 功能说明
atol() 函数用于将字符串转换为长整数(long 类型)。它是 atoi() 函数的变体,专门设计用于处理那些可能超出 int 类型范围,但仍处于 long 类型范围内的数值。
- 参数:
- str:要转换的 C 字符串,即以 null(\0)结尾的字符数组。
- 返回值:
- 若成功完成字符串到长整数的转换,则返回对应的 long 整数值。
- 若无法完成转换,则返回 0。
2.3 转换规则
- 忽略前导空格:在处理字符串时,首先跳过字符串开头所有空白字符,这些空白字符包括空格、制表符(\t)、换行符(\n)等。
- 识别正负号:在跳过前导空格后,若字符串中存在可选的 + 或 - 符号,该符号将决定最终转换得到的整数的正负性。
- 读取数字:从识别出正负号(若存在)之后的位置开始,连续读取数字字符(0 到 9),直到遇到第一个非数字字符为止。
- 停止转换:一旦遇到第一个非数字字符,立即停止解析过程,后续的字符将不再进行处理。
- 返回结果:将解析得到的数字序列转换为 long 类型并返回。
示例转换:
输入字符串 | 返回值 | 说明 |
---|---|---|
"123456789" | 123456789 | 十进制转换 |
"-987654321" | -987654321 | 负十进制转换 |
" +12345" | 12345 | 忽略前导空格和正号 |
"12345abc" | 12345 | 遇到非数字字符停止 |
"HelloWorld" | 0 | 无效输入,返回 0 |
"0000000000" | 0 | 前导零被忽略 |
2.4 注意事项
- 无法区分 0 和错误:
- 当字符串无法转换为有效的长整数时(例如输入为 "HelloWorld"),atol() 函数会直接返回 0。
- 这种情况下,无法通过返回值来判断是输入本身就为 0,还是由于输入错误导致无法转换。
- 溢出问题:
- 如果待转换的数值超出了 long 类型的表示范围(例如在 64 位系统中输入 "2147483648",这超出了 long 的最大值 2147483647),atol() 的行为是未定义的。
- 这可能导致函数返回一个错误的值,或者触发不可预测的行为,如程序崩溃。
- 不推荐用于用户输入:
- 由于 atol() 函数缺乏错误检测机制,它不适合处理来自不可信来源的输入,如用户输入。
- 在处理用户输入时,应该使用具有错误检测功能的函数,如 strtol(),以便能够正确处理各种错误情况。
- 简单场景适用:
- atol() 函数仅适用于那些已知格式正确、无需错误检测的简单转换场景。
- 例如,当处理硬编码的字符串或内部数据时,如果确定这些数据始终是有效的长整数格式,那么可以使用 atol() 进行转换。但即便如此,也需谨慎对待可能的溢出问题。
2.5 示例程序
#include <stdio.h>
#include <stdlib.h> // 必须包含这个头文件才能使用 atol()
int main()
{
// 示例 1:基本转换
printf("转换结果1: %ld\n", atol("123456789")); // 输出: 123456789
// 示例 2:带符号的数字
printf("转换结果2: %ld\n", atol("-987654321")); // 输出: -987654321
// 示例 3:带前导空格和符号
printf("转换结果3: %ld\n", atol(" +12345")); // 输出: 12345
// 示例 4:部分有效的数字
printf("转换结果4: %ld\n", atol("12345abc")); // 输出: 12345
// 示例 5:无效输入
printf("转换结果5: %ld\n", atol("HelloWorld")); // 输出: 0
// 示例 6:大数转换(在 long 范围内)
printf("转换结果6: %ld\n", atol("2147483647")); // 输出: 2147483647
// 示例 7:全是零
printf("转换结果7: %ld\n", atol("0000000000")); // 输出: 0
return 0;
}
程序在 VS Code 中的运行结果如下所示:
3 atoll() 函数
3.1 函数原型
#include <stdlib.h> // 必须包含这个头文件
long long atoll(const char *str);
3.2 功能说明
atoll() 函数用于将字符串转换为长长整数(long long 类型)。它是 atoi() 和 atol() 函数的变体,专门设计用于处理那些可能超出 int 或 long 类型范围,但仍处于 long long 类型范围内的数值。
- 参数:
- str:要转换的 C 字符串,即以 null(\0)结尾的字符数组。
- 返回值:
- 若成功完成字符串到长长整数的转换,则返回对应的 long long 整数值。
- 若无法完成转换,则返回 0。
3.3 转换规则
- 忽略前导空格:在处理字符串时,首先跳过字符串开头所有空白字符,这些空白字符包括空格、制表符(\t)、换行符(\n)等。
- 识别正负号:在跳过前导空格后,若字符串中存在可选的 + 或 - 符号,该符号将决定最终转换得到的整数的正负性。
- 读取数字:从识别出正负号(若存在)之后的位置开始,连续读取数字字符(0 到 9),直到遇到第一个非数字字符为止。
- 停止转换:一旦遇到第一个非数字字符,立即停止解析过程,后续的字符将不再进行处理。
- 返回结果:将解析得到的数字序列转换为 long long 类型并返回。
示例转换:
输入字符串 | 返回值 | 说明 |
---|---|---|
"1234567890123456789" | 1234567890123456789 | 十进制转换 |
"-987654321098765432" | -987654321098765432 | 负十进制转换 |
" +123456789" | 123456789 | 忽略前导空格和正号 |
"123456789abc" | 123456789 | 遇到非数字字符停止 |
"HelloWorld" | 0 | 无效输入,返回 0 |
"0000000000000000000" | 0 | 前导零被忽略 |
3.4 注意事项
- 无法区分 0 和错误:
- 当字符串无法转换为有效的长长整数时(例如输入为 "HelloWorld"),atoll() 函数会直接返回 0。
- 这种情况下,无法通过返回值来判断是输入本身就为 0,还是由于输入错误导致无法转换。
- 溢出问题:
- 如果待转换的数值超出了 long long 类型的表示范围(例如在 64 位系统中输入 "9223372036854775808",这超出了 long long 的最大值 9223372036854775807),atoll() 的行为是未定义的。
- 这可能导致函数返回一个错误的值,或者触发不可预测的行为,如程序崩溃。
- 不推荐用于用户输入:
- 由于 atoll() 函数缺乏错误检测机制,它不适合处理来自不可信来源的输入,如用户输入。
- 在处理用户输入时,应该使用具有错误检测功能的函数,如 strtoll(),以便能够正确处理各种错误情况。
- 简单场景适用:
- atoll() 函数仅适用于那些已知格式正确、无需错误检测的简单转换场景。
- 例如,当处理硬编码的字符串或内部数据时,如果确定这些数据始终是有效的长长整数格式,那么可以使用 atoll() 进行转换。但即便如此,也需谨慎对待可能的溢出问题。
3.5 示例程序
#include <stdio.h>
#include <stdlib.h> // 必须包含这个头文件才能使用 atoll()
int main()
{
// 示例 1:基本转换
printf("转换结果1: %lld\n", atoll("1234567890123456789")); // 输出: 1234567890123456789
// 示例 2:带符号的数字
printf("转换结果2: %lld\n", atoll("-987654321098765432")); // 输出: -987654321098765432
// 示例 3:带前导空格和符号
printf("转换结果3: %lld\n", atoll(" +123456789")); // 输出: 123456789
// 示例 4:部分有效的数字
printf("转换结果4: %lld\n", atoll("123456789abc")); // 输出: 123456789
// 示例 5:无效输入
printf("转换结果5: %lld\n", atoll("HelloWorld")); // 输出: 0
// 示例 6:大数转换(在 long long 范围内)
printf("转换结果6: %lld\n", atoll("9223372036854775807")); // 输出: 9223372036854775807
// 示例 7:全是零
printf("转换结果7: %lld\n", atoll("0000000000000000000")); // 输出: 0
return 0;
}
程序在 VS Code 中的运行结果如下所示:
4 atof() 函数
4.1 函数原型
#include <stdlib.h> // 必须包含这个头文件
double atof(const char *str);
4.2 功能说明
atof() 函数用于将字符串转换为双精度浮点数(double 类型)。它是 atoi() 和 atol() 函数的变体,专门设计用于处理那些可能包含小数点或科学计数法表示的浮点数值。
- 参数:
- str:要转换的 C 字符串,即以 null(\0)结尾的字符数组。
- 返回值:
- 若成功完成字符串到双精度浮点数的转换,则返回对应的 double 浮点数值。
- 若无法完成转换,则返回 0.0。
4.3 转换规则
- 忽略前导空格:在处理字符串时,首先跳过字符串开头所有空白字符,这些空白字符包括空格、制表符(\t)、换行符(\n)等。
- 识别正负号:在跳过前导空格后,若字符串中存在可选的 + 或 - 符号,该符号将决定最终转换得到的浮点数的正负性。
- 读取数字和小数点:从识别出正负号(若存在)之后的位置开始,连续读取数字字符(0 到 9)和小数点(.)。小数点用于分隔整数部分和小数部分。
- 识别指数部分(可选):在读取了数字和小数点之后,如果遇到 e 或 E,则可能后面跟着可选的 + 或 - 符号以及数字字符,这部分表示科学计数法中的指数部分。
- 停止转换:一旦遇到第一个非数字字符(且不是小数点或指数部分的 e/E 及其后续数字),立即停止解析过程,后续的字符将不再进行处理。
- 返回结果:将解析得到的数字序列(包括整数部分、小数部分和可能的指数部分)转换为 double 类型并返回。
示例转换:
输入字符串 | 返回值 | 说明 |
---|---|---|
"123.456" | 123.456 | 十进制小数转换 |
"-789.123" | -789.123 | 负十进制小数转换 |
" +42.0" | 42.0 | 忽略前导空格和正号 |
"123.456abc" | 123.456 | 遇到非数字字符停止 |
"HelloWorld" | 0.0 | 无效输入,返回 0.0 |
"1.23e4" | 12300.0 | 科学计数法转换 |
"1.23E-2" | 0.0123 | 负指数科学计数法 |
"0000.0000" | 0.0 | 前导零和小数点后零被忽略 |
"1e309" | inf | 超出范围,返回无穷大 |
"1e-309" | 0.0 | 超出范围,返回 0.0 |
4.4 注意事项
- 无法区分 0 和错误:
- 当字符串无法转换为有效的浮点数时(例如输入为 "HelloWorld"),atof() 函数会直接返回 0.0。
- 这种情况下,无法通过返回值来判断是输入本身就为 0.0,还是由于输入错误导致无法转换。因此,在需要严格区分输入错误和实际值为 0.0 的场景中,应避免使用 atof()。
- 溢出问题:
- 若待转换的数值超出了 double 类型的表示范围,atof() 的行为将依赖于具体实现,但通常会出现以下几种情况:
- 极小值:对于接近零但无法精确表示的极小值,可能会返回 0.0 或 nan(非数字)。
- 负溢出:对于负向超出范围的数值,通常会返回 -inf(负无穷大)。
- 正溢出:对于正向超出范围的数值,通常会返回 inf(无穷大)。
- 这些溢出情况可能导致程序逻辑错误或不可预测的行为,因此在处理可能超出 double 范围的数值时,应谨慎使用 atof()。
- 若待转换的数值超出了 double 类型的表示范围,atof() 的行为将依赖于具体实现,但通常会出现以下几种情况:
- 不推荐用于用户输入:
- 由于 atof() 函数缺乏错误检测机制,它无法有效处理来自不可信来源的输入,如用户输入。
- 在处理用户输入时,应使用具有错误检测功能的函数,如 strtod(),它提供了更详细的错误处理能力,包括检测无效输入、溢出等情况。
- 简单场景适用:
- atof() 函数仅适用于那些已知格式正确、无需错误检测的简单转换场景。
- 例如,当处理硬编码的字符串或内部数据时,如果确定这些数据始终是有效的浮点数格式,那么可以使用 atof() 进行转换。但在实际应用中,这种情况相对较少,因此 atof() 的使用场景相对有限。
4.5 示例程序
#include <stdio.h>
#include <stdlib.h> // 必须包含这个头文件才能使用 atof()
int main()
{
// 示例 1:基本转换
printf("转换结果1: %f\n", atof("123.456")); // 输出: 123.456000
// 示例 2:带符号的数字
printf("转换结果2: %f\n", atof("-789.123")); // 输出: -789.123000
// 示例 3:带前导空格和符号
printf("转换结果3: %f\n", atof(" +42.0")); // 输出: 42.000000
// 示例 4:部分有效的数字
printf("转换结果4: %f\n", atof("123.456abc")); // 输出: 123.456000
// 示例 5:无效输入
printf("转换结果5: %f\n", atof("HelloWorld")); // 输出: 0.000000
// 示例 6:科学计数法
printf("转换结果6: %f\n", atof("1.23e4")); // 输出: 12300.000000
// 示例 7:负指数
printf("转换结果7: %f\n", atof("1.23E-2")); // 输出: 0.012300
// 示例 8:全是零
printf("转换结果8: %f\n", atof("0000.0000")); // 输出: 0.000000
// 示例 9:数字太大超出 double 范围
printf("转换结果9: %f\n", atof("1e309")); // 输出: inf
// 示例 10:数字太小超出 double 范围
printf("转换结果10: %f\n", atof("1e-309")); // 输出: 0.000000
// 示例 11:非数字字符串
printf("转换结果11: %f\n", atof("NAN")); // 输出: 0.000000 , 具体行为可能因编译器和库实现而异
return 0;
}
程序在 VS Code 中的运行结果如下所示:
5 字符串转数值函数总结
函数名 | 返回值类型 | 功能 | 无法转换时的返回值 | 溢出时的行为 | 适用场景 |
---|---|---|---|---|---|
atoi | int | 将字符串转换为 int 类型 | 返回 0 | 结果不可预测(可能错误值) | 简单整数转换(已知格式正确) |
atol | long | 将字符串转换为 long 类型 | 返回 0 | 结果不可预测(可能错误值) | 需要更大整数范围的简单转换 |
atoll | long long | 将字符串转换为 long long 类型 | 返回 0 | 结果不可预测(可能错误值) | 需要极大整数范围的简单转换 |
atof | double | 将字符串转换为 double 类型 | 返回 0.0 | 可能返回 inf 或 nan | 简单浮点数转换(已知格式正确) |
- 无法区分 0 和错误:
- 所有函数在无法转换时返回 0(atof 返回 0.0),无法区分输入是 "0" 还是无效字符串(如 "Hello")。
- 溢出问题:
- atoi、atol、atoll 在溢出时行为不可预测(可能返回错误值)。
- atof 在溢出时可能返回 inf(无穷大)或 nan(非数字)。
- 适用场景:
- 适合已知格式正确的简单转换(如配置文件中的固定格式数字)。
- 不推荐用于用户输入:因为无法可靠检测错误,建议使用更安全的函数(如 strtol、strtoll、strtod)。
- 更安全的替代方案:
- 使用 strtol、strtoll、strtoul、strtoull 等函数,它们可以:
- 检测错误(通过 endptr 参数)。
- 检测溢出(通过 errno)。
- 支持进制转换(如二进制、八进制、十进制、十六进制)。
- 下一章预告:
- 详细讲解 strtol、strtoll、strtoul、strtoull、strtof、strtod、strtold 函数的用法,包括错误检测、进制转换和溢出处理。
- 提供实际代码示例,帮助开发者安全处理字符串转数值的场景。
- 使用 strtol、strtoll、strtoul、strtoull 等函数,它们可以: