目录
1 sprintf
1.1 函数原型
1.2 功能说明
1.3 案例演示
1.4 注意事项
2 sscanf
2.1 函数原型
2.2 功能说明
2.3 案例演示
2.4 注意事项
1 sprintf
1.1 函数原型
sprintf 函数是 C 语言标准库中的一个函数,用于将格式化的数据写入字符串。其函数原型定义在 <stdio.h> 头文件中。
#include <stdio.h>
int sprintf(char *str, const char *format, ...);
- 参数:
- char *str:指向一个字符数组的指针,该数组足够大以存储生成的格式化字符串。这个数组必须已经分配了足够的空间来容纳结果字符串,包括结尾的空字符(\0)。
- const char *format:一个格式字符串,用于指定后续参数如何被格式化和插入到结果字符串中。这个字符串可以包含文本、格式说明符(如 %d、%s、%f 等),以及转义序列(如 \n、\t 等),同 printf 函数的使用。
- ...:可变数量的参数,其类型和数量由 format 字符串中的格式说明符决定,同 printf 函数的使用。这些参数将被格式化为字符串,并插入到 str 指向的数组中。
- 返回值:成功时,sprintf 返回写入的字符数(不包括结尾的空字符)。如果发生错误,则可能返回负值,但这种情况在实际应用中较为罕见。
1.2 功能说明
sprintf 函数的主要功能是将格式化的数据写入到字符串中,而不是像 printf 那样输出到标准输出设备(通常是屏幕)。这使得 sprintf 非常适用于需要生成格式化字符串并存储在变量中的场景。
与 printf 相比,sprintf 多了一个参数,即第一个参数是要写入的目标字符串,而后面的参数与 printf 保持一致。
简而言之,sprintf 是将内容写入字符串而不是直接输出。
1.3 案例演示
#include <stdio.h>
int main()
{
char buffer[256]; // 分配一个足够大的缓冲区来存储结果字符串
int num1 = 123;
float num2 = 456.78f;
char ch = 'A';
char str[] = "Hello, World!";
int result;
// 使用 sprintf 将格式化的数据写入 buffer
// 注意:返回值是写入的字符数(不包括'\0')
result = sprintf(buffer, "Integer: %d, Float: %.2f, Character: %c, String: %s.\n", num1, num2, ch, str);
// 输出生成的字符串
printf("使用 sprintf 生成的字符串:\n%s", buffer);
// 输出 sprintf 的返回值
printf("sprintf 的返回值(一般不适用它): %d\n", result);
return 0;
}
输出结果如下所示:
1.4 注意事项
缓冲区溢出:在使用 sprintf 时,必须确保目标字符串数组 str 有足够的空间来存储生成的字符串,包括末尾的空字符 '\0'。否则,可能会导致缓冲区溢出,这是一个严重的安全问题。
返回值检查:虽然 sprintf 的返回值(写入的字符数)在大多数情况下可能不是必需的,但在某些情况下,检查返回值可以帮助识别潜在的错误或溢出情况。
性能考虑:在性能敏感的应用中,频繁使用 sprintf 可能会引入不必要的开销,因为它涉及到字符串的复制和格式化操作。在这种情况下,可能需要考虑使用更高效的字符串处理函数或方法。
2 sscanf
2.1 函数原型
sscanf 函数是 C 语言标准库中的一个函数,用于从字符串中读取格式化的输入。它的函数原型定义在 <stdio.h> 头文件中。函数原型如下:
#include <stdio.h>
int sscanf(const char *str, const char *format, ...);
- 参数:
- const char *str:指向要扫描的字符串的指针。
- const char *format:一个格式字符串,指定了后续参数应该如何从 str 中被解析。这个字符串可以包含文本、格式说明符(如 %d、%s、%f 等)以及空白符(空格、制表符等),用于分隔输入项。
- ...:可变数量的参数,这些参数指向变量的地址。sscanf 将根据 format 字符串中的格式说明符,从 str 中解析出数据,并存储到这些变量中。
- 返回值:
- 成功时,sscanf 返回成功匹配并赋值的输入项的数量。
- 如果遇到输入结束或遇到格式错误前没有匹配任何输入项,则返回 0。
- 如果发生读取错误,则返回 EOF。
2.2 功能说明
sscanf 函数模仿了 scanf 的行为,不过它是从字符串而非标准输入中读取数据,这使其特别适合解析具有特定格式的字符串内容。sscanf 支持多种数据类型,例如整数、浮点数和字符串,通过格式化字符串来指导数据的解析方式。
相较于 scanf,sscanf 额外需要一个参数,即要从中提取数据的字符串,而其余参数则与 scanf 相同。
简而言之,sscanf 的功能是从字符串中按照指定格式提取数据。
2.3 案例演示
#include <stdio.h>
int main()
{
char input[] = "整数:123,浮点数:456.78,字符串:Hello,World!";
int intValue;
float floatValue;
char stringValue[50];
// 尝试从 input 中解析一个整数、一个浮点数和一个字符串
// 注意 %s 遇到空白符会停止读取,所以 Hello,World! 中间没有空格
int numItemsRead = sscanf(input, "整数:%d,浮点数:%f,字符串:%s", &intValue, &floatValue, stringValue);
// 如果使用下面这行代码,sscanf 不会成功读取,因为指定格式不对!!!
// int numItemsRead = sscanf(input, "%d %f %s", &intValue, &floatValue, stringValue);
// 检查是否成功读取了三个项
if (numItemsRead == 3)
{
printf("成功解析:\n");
printf("整数: %d\n", intValue);
printf("浮点数: %.2f\n", floatValue);
printf("字符串: %s\n", stringValue);
}
else
{
// 如果未成功读取三个项,则输出错误信息
printf("解析失败或格式不匹配,读取的项数: %d\n", numItemsRead);
}
return 0;
}
注意:%s 在遇到空白字符时会停止读取,因此上诉代码中 Hello,World! 中间不能有空格。
输出结果如下所示:
2.4 注意事项
缓冲区溢出:与 scanf 类似,sscanf 不会检查目标变量的大小,可能会导致缓冲区溢出。因此,在使用时应当确保目标变量有足够的空间来存储解析的数据。
格式匹配:sscanf 严格根据格式字符串进行匹配,包括空格和特殊字符。如果格式字符串与输入字符串不匹配,sscanf 可能无法正确解析数据。
返回值检查:始终检查 sscanf 的返回值,以确保正确读取了预期数量的输入项。如果返回值小于预期,可能表示输入数据不符合预期格式。
灵活性:虽然 sscanf 提供了从字符串中解析数据的灵活性,但在处理复杂或不规则的输入格式时,可能需要结合使用其他字符串处理函数(如 strtok、strchr 等)来辅助解析。