ZetCode

C sprintf 函数

最后修改日期:2025 年 4 月 6 日

字符串格式化是 C 编程中的一项关键技能,它能让您高效地创建格式化字符串。sprintf 函数是实现此目的的强大工具,但需要谨慎使用以避免缓冲区溢出。本教程将深入讲解 sprintf,演示其用法,并展示更安全的替代方法,如 snprintf。掌握字符串格式化可以确保程序中可靠的文本处理和输出生成。

什么是 sprintf?

C 语言中的 sprintf 函数将格式化数据写入字符串缓冲区。它的工作方式类似于 printf,但它将结果存储在内存中,而不是打印到标准输出。该函数接受一个目标缓冲区、一个格式字符串和可选参数。虽然强大,但 sprintf 不够安全,因为它不检查缓冲区大小。在安全至关重要时,请始终优先使用 snprintf

基本的 sprintf 示例

让我们从一个简单的示例开始,演示基本的字符串格式化。

basic_sprintf.c
#include <stdio.h>

int main() {
    char buffer[100];
    int age = 25;
    float height = 1.75f;
    
    sprintf(buffer, "I am %d years old and %.2f meters tall.", age, height);
    
    printf("Formatted string: %s\n", buffer);
    return 0;
}

此示例使用 sprintf 将整数和浮点数格式化为字符串。格式说明符 %d%.2f 控制值的显示方式。缓冲区必须足够大才能容纳结果。然后使用 printf 打印格式化后的字符串。

格式化多个值

sprintf 可以将不同类型的值格式化到单个字符串中。

multi_format.c
#include <stdio.h>

int main() {
    char result[150];
    char name[] = "Alice";
    int score = 95;
    double average = 87.456;
    
    sprintf(result, "Student: %s\nScore: %d/100\nClass average: %.1f%%", 
            name, score, average);
    
    puts(result);
    return 0;
}

此代码使用字符串、整数和浮点值格式化一个学生记录。格式字符串中的 %% 会产生一个字面上的百分号。请注意,缓冲区大小(150)大于预期输出,以防止溢出。puts 函数打印完整的格式化字符串。

安全的替代方法:snprintf

snprintf 函数是 sprintf 的安全版本。

safe_snprintf.c
#include <stdio.h>

int main() {
    char buffer[20];
    int written = snprintf(buffer, sizeof(buffer), 
                         "The answer is %d", 42);
    
    if (written >= sizeof(buffer)) {
        printf("Warning: Truncation occurred\n");
    }
    
    printf("Buffer: '%s'\n", buffer);
    printf("Characters written: %d\n", written);
    return 0;
}

snprintf 将缓冲区大小作为第二个参数,从而防止缓冲区溢出。它返回如果缓冲区足够大将被写入的字符数。这可以帮助您检测截断。在生产代码中,请始终使用 snprintf 而不是 sprintf

构建文件路径

sprintf 在动态构建文件路径时很有用。

file_path.c
#include <stdio.h>

int main() {
    char path[256];
    int user_id = 42;
    
    sprintf(path, "/home/user%d/data/file.txt", user_id);
    
    printf("Constructed path: %s\n", path);
    
    // Now using snprintf for safety
    snprintf(path, sizeof(path), 
            "/home/user%d/data/file.txt", user_id);
    
    printf("Safe path: %s\n", path);
    return 0;
}

此示例展示了如何通过插入数字 ID 来构建文件路径。第一个版本使用 sprintf,如果缓冲区太小则存在风险。第二个版本演示了更安全的 snprintf 方法。请始终确保您的缓冲区足够大以应对最坏情况。

格式化日期字符串

使用 sprintf 和日期组件创建自定义日期格式。

date_format.c
#include <stdio.h>

int main() {
    char date_str[50];
    int year = 2025;
    int month = 4;
    int day = 6;
    
    sprintf(date_str, "%04d-%02d-%02d", year, month, day);
    
    printf("ISO date format: %s\n", date_str);
    
    // Alternative format
    sprintf(date_str, "%d/%d/%d", month, day, year);
    printf("US date format: %s\n", date_str);
    
    return 0;
}

此代码将日期组件格式化为不同的字符串表示形式。%04d 确保年份为 4 位数并带前导零。%02d 将月份和日期格式化为两位数。第二个 sprintf 演示了美国常见的不同日期格式。

字符串格式化的最佳实践

来源

C sprintf 文档

本教程展示了 sprintf 的强大功能和风险,从基本格式化到文件路径构建,都提供了实际示例。请记住,在生产代码中,请始终优先使用 snprintf 来进行更安全的字符串操作。

作者

我的名字是 Jan Bodnar,我是一名充满激情的程序员。自 2007 年以来,我通过 1,400 多篇文章和 8 本电子书分享我的专业知识。凭借十多年的教学经验,我致力于让编程变得易于理解且引人入胜。

列表 C 标准库