{ }codelper

学习 › C

进阶 · 19

字符串处理

截取、查找、替换、去除首尾空白、比较、补齐对齐。

拿到输入后,常常要先整理(去掉首尾空白),再找到并截取需要的部分,最后改变形式再输出。
下面的示例依次用到这些工具。

#include <ctype.h>#include <stdio.h>#include <string.h> char *trim(char *s) {    while (isspace((unsigned char)*s)) s++;    char *end = s + strlen(s);    while (end > s && isspace((unsigned char)end[-1])) *--end = '\0';    return s;} int main(void) {    char line[1024], date[64], a[64], b[64];    int n;    fgets(line, sizeof line, stdin);    scanf("%63s %63s %63s %d", date, a, b, &n);    char *text = trim(line);    printf("[%s]\n", text);    printf("%.5s\n", text);    char *found = strstr(text, "World");    int i = found ? (int)(found - text) : -1;    printf("%d\n", i);    printf("%.5s\n", text + i);    printf("%d\n", strstr(text, "Bye") ? (int)(strstr(text, "Bye") - text) : -1);    for (char *p = date; *p; p++)        if (*p == '-') *p = '/';    printf("%s\n", date);    int c = strcmp(a, b);    printf("%d\n", (c > 0) - (c < 0));    printf("%03d\n", n);    return 0;}
stdin
   Hello, World   
2026-11-10
pear apple
7
stdout
[Hello, World]
Hello
7
World
-1
2026/11/10
1
007

要点

  • 整理就是去掉首尾空白。
    读进来的行先整理再用,比较安全。
  • 查找返回第一次出现的位置。
    找不到时大多返回 -1,但各语言不完全一样。
  • 截取时,第二个数的含义因语言而异:有的是结束位置(不含该位置),有的是字符个数。
  • 替换大多会替换全部,但 JavaScript 的 replace 只替换第一个。
  • 比较返回负数、0 或正数。
    只有符号可靠,数值大小没有意义。
  • 补齐是在前面填字符凑够宽度,比如把 7 变成 007。

各语言的写法

Pythonstrip()、find(找不到返回 -1,index 会报错)、t[7:12](结束位置)、replace(全部)、rjust(3, "0")
JavaScripttrim()、indexOf、slice(7, 12)(结束位置)、replace 只换第一个、replaceAll 换全部、padStart(3, "0")。
localeCompare 遵循区域设置
TypeScript和 JavaScript 一样
Javastrip()、indexOf、substring(7, 12)(结束位置)、replace(全部;replaceAll 用正则)、compareTo(只信符号)
C#Trim()、IndexOf、Substring(7, 5)(字符个数)、Replace(全部)、PadLeft(3, '0')。
string.Compare 和 IndexOf(string) 遵循区域设置,要按字符编码比较就加 StringComparison.Ordinal 或用 string.CompareOrdinal
C++没有整理函数,要自己截取。
find(找不到返回 std::string::npos)、substr(7, 5)(字符个数)、compare。
全部替换要用循环。
补齐用 setw 加 setfill
C没有整理和全部替换,要自己写。
strstr(找不到返回 NULL),截取用 printf("%.5s", text + 7)(起始地址加字符数),比较用 strcmp,补齐用 printf("%03d")
Craykon去空白()、查找位置(找不到返回 -1)、截取(7, 5)(字符个数)、替换(全部)、左填充(3, "0")

常见错误

以为 compareTo 会返回 1Java · C · C++ · C#

System.out.println("pear".compareTo("apple"));

→ 15 — 也就是 'p' - 'a'

只看符号,比如 > 0、< 0。

搞混了截取的第二个数C# · Java · JavaScript

"Hello, World".Substring(7, 12)  // C#
"Hello, World".substring(7, 5)   // Java, JavaScript

→ C# 越界报错,Java 也报错。JavaScript 则悄悄交换两个数,返回 ", "

先确认在这门语言里第二个数是结束位置还是字符个数。

以为 replace 会替换全部JavaScript · TypeScript

console.log("2026-11-10".replace("-", "/"));

→ 2026/11-10 — 只替换了第一个

要全部替换请用 replaceAll。
另外注意 Java 的 replaceAll 用正则,"a.b".replaceAll(".", "-") 得到 "---"。

各语言的差异
在 Windows 上生成的输入,行尾是 \r\n。
Java nextLine()、C# ReadLine()、Craykon 读行() 会把 \r 一起去掉,但 Python input()(在 Linux 和 macOS 上)、JavaScript split("\n")、C fgets、C++ getline 会留下它,于是 "World\r" == "World" 为假;读进来的行先整理再用。

练习题