標準庫方案 (C11 strstrip 尚未標準化,常用自寫)
// 就地修改:移除尾部 space, \t, \n, \r, \v, \f
void rtrim(char *s) {
if (!s) return;
char *p = s + strlen(s);
while (p > s && isspace((unsigned char)*(p - 1))) p--;
*p = '\0';
}
完整去除首尾空白
void trim(char *s) {
if (!s) return;
// 1. 尾部
char *end = s + strlen(s);
while (end > s && isspace((unsigned char)*(end - 1))) end--;
*end = '\0';
// 2. 首部
char *start = s;
while (*start && isspace((unsigned char)*start)) start++;
if (start != s) memmove(s, start, end - start + 1); // 含 \0 移動
}
關鍵細節
isspace 參數需轉 unsigned char 避免負值未定義行為 (針對非 ASCII 字符)。
memmove 處理重疊記憶體安全,memcpy 不安全。
- **不可用於字串常量** (如
char *s = " abc "),會導致段錯誤 —— 需複製到可寫緩衝區。
C++ 對比
// C++17 std::string_view + 算法
#include
#include
#include
std::string_view trim_view(std::string_view sv) {
auto not_space = [](char c){ return !std::isspace(static_cast(c)); };
auto first = std::find_if(sv.begin(), sv.end(), not_space);
auto last = std::find_if(sv.rbegin(), sv.rend(), not_space).base();
return (first < last) ? std::string_view(first, last - first) : std::string_view();
}
無標準庫手寫 strlen (教學用)
size_t my_strlen(const char *s) {
size_t len = 0;
while (s[len]) len++;
return len;
}