從一個字串中去除多餘的空格。
阿新 • • 發佈:2019-01-30
字串中如果有一個地方由一個或多個連續的空格組成,就把它們改成單個空格字元。注意當遍歷整個字串時要確保它以NUL字元結尾。
此處的空格的含義包括但不限於空格字元,為什麼呢?空格、水平製表、垂直製表、換頁、換行、回車在控制檯輸出的時候都會讓我們感覺字元之間由空格隔開了,所以,在遍歷字串的時候,應該對上述特殊字元進行處理。只有這樣,才更符合我們的習慣。
處於對程式健壯性的考慮,我在刪除多餘空格函式deblank函式體最前面加上了斷言,只有輸入的指標引數非空進行後續操作才是合法的,不然會產生不可預料的後果。本程式在VS2017下編譯執行通過。#include<stdio.h> #include<assert.h> #define NUL '\0' int is_white(int ch) { return ' ' == ch || '\t' == ch || '\v' == ch || '\f' == ch || '\n' == ch || '\r' == ch; } void deblank(char *str) { assert(NULL != str); /* **將兩個指標都指向字串的首部。 */ char *src = str; char *dest = str; /* **遍歷整個字元陣列 */ for (; *src != NUL;) { /* **首次出現空格,進行復制, **緊接著再次出現,直接跳過。 */ if (is_white(*src)) { *dest++ = ' '; src++; while (is_white(*src)) { src++; } } /* **如果不是空格的話,後面的值複製到前面去。 */ else { *dest++ = *src++; } } /* **新增結束符 '\0'。 */ *dest = NUL; } int main() { char str[] = "I\t\t\tlike it !"; printf("刪除多餘的空格前:\n%s\n", str); deblank(str); printf("刪除多餘的空格後:\n%s\n", str); return 0; }
對程式進行分析,我們可以發現,判斷是否首次是否為“空格”,出現了兩重迴圈,我在第一次創作這篇部落格的半個月後,突然想到了改進版本:
- 新的版本只出現了一重迴圈。
#include<stdio.h> #include<assert.h> #define NUL '\0' int is_white(int ch) { return ' ' == ch || '\t' == ch || '\v' == ch || '\f' == ch || '\n' == ch || '\r' == ch; } void deblank(char* str) { assert(NULL != str); /* **將兩個指標都指向字串的首部。 */ int tag = false;//判斷是否為首次出現空格。 char *src = str; char *dest = src; /* **遍歷整個字元陣列 */ for (; *src != NUL;) { /* **首次出現空格,進行復制, **緊接著再次出現,直接跳過。 */ if (is_white(*src)) { *dest = ' '; if (tag) { dest++; tag = false; } src++; } else { tag = true; *dest++ = *src++; } } /* **新增結束符 '\0'。 */ *dest = NUL; } int main() { char str[] = "I\t\t\tlike it !"; printf("刪除多餘的空格前:\n%s\n", str); deblank(str); printf("刪除多餘的空格後:\n%s\n", str); return 0; }