首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> 關於C語言

C語言文件寫入字段對齊與填充實現:左/右對齊、空格/零填充完整代碼

     編輯:關於C語言

業務場景

生成固定格式文本文件(如銀行話單、EDI 報文),要求每字段固定寬度 10 字符,不足部分按規則填充:

  • 左對齊,右側填空格
  • 右對齊,左側填空格
  • 左對齊,右側填 0
  • 右對齊,左側填 0

核心技術:`snprintf` 格式化字符串

模式格式字符串示例輸入 "abc"說明
左對齊,右填空格`%-10s``"abc "`標準左對齊
右對齊,左填空格`%10s``" abc"`標準右對齊
左對齊,右填 0`%-s%0*d``"abc0000000"`字符串 + 寬度為 (10-len) 的零填充整數
右對齊,左填 0`%0*d%s``"0000000abc"`零填充整數 + 字符串

完整實現代碼

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

typedef int INT32;
typedef char INT8;

void write_aligned_field(INT32 align_mode, const INT8 *input) {
    INT8 buffer[64] = {0};
    const INT32 FIELD_WIDTH = 10;
    INT32 len = strlen(input);

    switch (align_mode) {
        case 1:  // 左對齊,右填空格
            snprintf(buffer, sizeof(buffer), "%-*s", FIELD_WIDTH, input);
            break;
        case 2:  // 右對齊,左填空格
            snprintf(buffer, sizeof(buffer), "%*s", FIELD_WIDTH, input);
            break;
        case 3:  // 左對齊,右填 0
            snprintf(buffer, sizeof(buffer), "%-s%0*d", input, FIELD_WIDTH - len, 0);
            break;
        case 4:  // 右對齊,左填 0
            snprintf(buffer, sizeof(buffer), "%0*d%s", FIELD_WIDTH - len, 0, input);
            break;
        default:
            fprintf(stderr, "無效模式: %d\n", align_mode);
            return;
    }

    FILE *fp = fopen("output.txt", "w");
    if (fp) {
        fputs(buffer, fp);
        fclose(fp);
        printf("寫入成功: [%s]\n", buffer);
    } else {
        perror("文件打開失敗");
    }
}

int main() {
    INT32 mode;
    INT8 input[64];
    printf("輸入模式 (1-4) 和字符串: ");
    scanf("%d %63s", &mode, input);
    write_aligned_field(mode, input);
    return 0;
}

格式字符串深度解析

1. `%*s` / `%-*s` 動態寬度

snprintf(buf, size, "%*s", width, str);      // 右對齊,寬度由 width 指定
snprintf(buf, size, "%-*s", width, str);     // 左對齊
  • `*` 表示寬度從參數讀取
  • 配合 `FIELD_WIDTH - len` 實現精確填充

2. `%0*d` 零填充整數

snprintf(buf, size, "%0*d", width, 0);  // 輸出 width 個 '0'
  • `0` 標誌:零填充
  • `*`:寬度動態
  • 值固定為 `0`,產生純零串

3. 組合招式

// 左對齊右填0:字符串 + 零串
"%-s%0*d"  →  input + (width-len)個'0'

// 右對齊左填0:零串 + 字符串
"%0*d%s"   →  (width-len)個'0' + input

運行示例

輸入: 1 hello
輸出: [hello     ]  (左對齊,右5空格)

輸入: 2 hello
輸出: [     hello]  (右對齊,左5空格)

輸入: 3 hello
輸出: [hello00000]  (左對齊,右5零)

輸入: 4 hello
輸出: [00000hello]  (右對齊,左5零)

工程級擴展建議

  1. 多字段結構體序列化:定義字段描述表 `{name, width, align, pad_char}`,循環格式化
  2. 2. 大端/小端數值字段:數值轉十六進制字符串後再對齊 3. 流式寫入:避免大緩衝區,直接 `fprintf(fp, fmt, ...)` 4. 校驗機制:寫入後 `fread` 回讀驗證長度與內容 5. 跨平台換行:Windows `\r\n`、Linux `\n` 可配置

常見坑點

| 坑點 | 後果 | 修正 | |------|------|------| | `sprintf` 無長度檢查 | 緩衝區溢出 | **永遠用 `snprintf`** | | `FIELD_WIDTH - len` 為負 | 格式化異常/崩潰 | `if (len > FIELD_WIDTH) len = FIELD_WIDTH;` 截斷 | | 輸入含 `%` 字符 | 被誤認為格式符 | 純字符串填充場景安全;若需格式化輸入,用 `%%` 轉義 | | 多線程並發寫同一文件 | 數據交織 | 每線程獨立文件或加鎖 |

總結

利用 `snprintf` 的動態寬度 `*`、零填充 `0`、左對齊 `-` 三大標準格式修飾符組合,即可實現所有固定寬度字段對齊填充需求。本文封裝的 `write_aligned_field` 函數可直接集成到話單生成、報文構建等固定格式文件輸出系統中。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved