首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 更多程式語言 >> 程式設計疑難解答

C 語言循環生成序列文件名:sprintf 格式化字符串實戰技巧

     編輯:程式設計疑難解答

需求場景

在無限循環 while(1) 中,需要動態生成遞增的文件名:test1.jpg、test2.jpg、test3.jpg… 用於圖片保存、日誌輪轉等場景。

核心解決方案

標準 sprintf 實現

int i;
for (i = 1; i < 100; i++) {
    char outImageName1[32] = {0};  // 足夠容納 "test999999999.jpg"
    sprintf(outImageName1, "test%d.jpg", i);
    printf("%s\n", outImageName1);
    
    // 實際業務調用
    // saveImage(outImageName1, imageData);
}

關鍵點解析

  • 緩衝區大小:32 字節足夠應對 int 最大值(10 位數)+ 固定前綴後綴
  • 初始化:{0} 確保字符串以 \0 結尾,防止殘留數據
  • 格式化字符串:%d 自動處理整數轉十進制字符串,無需手動拼接
  • 作用域:變量在循環內聲明,每次迭代重新分配棧內存,線程安全

進階變體

帶前導零的固定寬度(便於排序)

sprintf(outImageName1, "test%04d.jpg", i); // test0001.jpg, test0002.jpg...

時間戳 + 序號(高併發唯一性)

char filename[64];
time_t now = time(NULL);
struct tm *tm_info = localtime(&now);
strftime(filename, sizeof(filename), "img_%Y%m%d_%H%M%S_", tm_info);
sprintf(filename + strlen(filename), "%04d.jpg", sequence++);

線程安全版本(C11 / POSIX)

// C11 標準
snprintf(outImageName1, sizeof(outImageName1), "test%d.jpg", i);

// POSIX 線程安全
snprintf(outImageName1, sizeof(outImageName1), "test%d.jpg", i);

常見錯誤與避坑

錯誤代碼問題後果
char *name = "test.jpg"; name[4] = '1';修改字符串字面量未定義行為,段錯誤
sprintf(buf, "test%d.jpg", i); // buf 未分配緩衝區未分配/太小緩衝區溢出,安全漏洞
static char name[32]; sprintf(name, ...); // 多線程靜態緩衝區共享數據競爭,文件名錯亂
i++ 在 sprintf 參數中副作用順序不定序號跳躍或重複

工程化建議

  1. 封裝為工具函數:
    int generate_filename(char *buf, size_t bufsz, const char *prefix, 
                          const char *suffix, int seq) {
        return snprintf(buf, bufsz, "%s%d%s", prefix, seq, suffix);
    }
  2. 配合原子計數器:多線程環境使用 atomic_int 或互斥鎖保護序號
  3. 添加上限檢查:防止序號溢出導致文件名衝突或緩衝區溢出
  4. 單元測試:驗證邊界值(1、99999、INT_MAX)、併發場景、異常輸入

擴展:Windows API 替代方案

// Windows 安全字符串函數
#include <strsafe.h>
StringCchPrintfA(outImageName1, 32, "test%d.jpg", i);

// MFC CString 更簡潔
CString strName;
strName.Format(_T("test%d.jpg"), i);
// 轉 char* 時注意編碼:CT2A(strName) 或 strName.GetString()
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved