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

C 語言字串處理實戰:將連續空格壓縮為製表符與空格

     編輯:程式設計疑難解答

題目需求

讀取輸入行,將連續空格序列按以下規則替換:

  • 1 個空格 → 保留 1 個空格
  • 2 個空格 → 保留 2 個空格
  • ≥3 個空格 → 每 3 個空格替換為 1 個製表符 \t,餘數保留空格

例如:"a b c"(3+4 空格)→ "a\tb\t c"(1 tab + 1 tab + 1 space)。

原始代碼主要問題

  1. 迴圈變數混亂:外層 `j` 與內層 `j++` 衝突,導致漏掉/重複處理字元。
  2. 計數器未重置:`ecount` 未在每組空格前歸零,累積錯誤。
  3. 賦值與比較搞混:`if (c = '\n')` 應為 `==`。
  4. 緩衝區未清空:`newline` 未以 `\0` 結尾,`printf("%s")` 會讀越界。
  5. `gets()` 不安全:已棄用,易造成緩衝區溢位,改用 `fgets()`。

修正後完整代碼(含註釋)

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

#define MAXIMUM 1000

// 讀取一行(含換行),返回長度;EOF 或空行返回 0
int getline(char *line) {
    int i, c;
    for (i = 0; (c = getchar()) != EOF && c != '\n'; i++)
        line[i] = c;
    if (i == 0 && c == EOF) return 0; // 檔案結束且無內容
    if (c == '\n') line[i++] = '\n';   // 保留換行
    line[i] = '\0';
    return i;
}

int main() {
    char line[MAXIMUM];
    char newline[MAXIMUM];
    int len;

    while ((len = getline(line)) > 0) {
        int j = 0, k = 0;
        // 處理每一字元
        while (j < len) {
            if (line[j] != ' ') {
                newline[k++] = line[j++];
            } else {
                // 統計連續空格數
                int ecount = 0;
                int i = j;
                while (i < len && line[i] == ' ') {
                    ecount++; i++;
                }
                j = i; // 跳過這組空格

                // 依規則轉換
                int tab_count = ecount / 3;
                int space_count = ecount % 3;
                for (int n = 0; n < tab_count; n++)    newline[k++] = '\t';
                for (int n = 0; n < space_count; n++)  newline[k++] = ' ';
            }
        }
        newline[k] = '\0'; // 關鍵:字串結束符
        printf("%s", newline); // 已含換行,不再加 \n
    }
    return 0;
}

關鍵修正點解析

問題修正
外層 `for` 迴圈內修改 `j`改用 `while (j < len)` 手動控制 `j` 推進
`ecount` 未歸零在每組空格處理前 `int ecount = 0;`
`if (c = '\n')`改為 `if (c == '\n')`
`newline` 缺 `\0`迴圈結束後 `newline[k] = '\0';`
使用 `gets()`自寫 `getline()` 基於 `getchar()`,安全可控

測試範例

輸入:
a   b    c     d
(a+3空格+b+4空格+c+5空格+d)

輸出:
a→b→c→ d
(視覺化:→ 代表 tab,空格顯示為空格)
實際輸出字串:'a','\t','b','\t','c','\t',' ','d','\n'

延伸思考

  • 若需支援 Unicode/多位元組字元,需用 `wchar_t` 或 UTF-8 處理庫。
  • 大檔案處理時,可改用流式讀寫,避免載入整行到記憶體。
  • 單元測試應覆蓋:0/1/2/3/4/5/6 空格、行首行尾空格、純空格行、空行、EOF 等邊界。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved