快速开始
Windows 用户
如果你在 Windows 环境下,可以直接使用以下命令:
for /r . %i in (*.c *.h) do clang-format -i "%i"
Linux/Unix 用户
如果你在 Linux/Unix 环境下,可以使用:
find . -name "*.c" -o -name "*.h" | xargs clang-format -i
基本命令
Linux/Unix 系统
find . -name "*.c" -o -name "*.h" | xargs clang-format -i
Windows 系统
for /r . %i in (*.c *.h) do clang-format -i "%i"
这个命令可以批量格式化当前目录及子目录下的所有 C 和 H 文件。
环境配置
1. 安装 clang-format
Windows
# 使用包管理器安装
# Chocolatey
choco install llvm
# Scoop
scoop install llvm
# 或者从官网下载安装包
# https://releases.llvm.org/download.html
Linux
# Ubuntu/Debian
sudo apt-get install clang-format
# CentOS/RHEL
sudo yum install clang-tools-extra
# 或者使用包管理器
sudo dnf install clang-tools-extra
macOS
# 使用 Homebrew
brew install clang-format
# 或者安装 Xcode Command Line Tools
xcode-select --install
2. 验证安装
clang-format --version
3. 配置 clang-format 样式文件
在项目根目录创建 .clang-format 文件:
# 基于 LLVM 风格
BasedOnStyle: LLVM
# 缩进设置
IndentWidth: 4
TabWidth: 4
UseTab: Never
# 行长度
ColumnLimit: 100
# 大括号风格
BreakBeforeBraces: Attach
# 函数参数换行
AllowAllParametersOfDeclarationOnNextLine: true
BinPackParameters: false
# 指针和引用对齐
PointerAlignment: Left
ReferenceAlignment: Left
# 空格设置
SpaceAfterCStyleCast: false
SpaceBeforeParens: ControlStatements
SpaceInEmptyParentheses: false
# 换行设置
BreakConstructorInitializers: BeforeColon
BreakAfterJavaFieldAnnotations: false
BreakStringLiterals: true
命令详解
Linux/Unix 基本语法
find [路径] [查找条件] | xargs [命令] [参数]
Windows 基本语法
for /r [路径] %i in (文件模式) do [命令] "%i"
参数说明
Linux/Unix
find .- 从当前目录开始查找-name "*.c"- 查找 .c 文件-o- 或者(OR 操作符)-name "*.h"- 查找 .h 文件|- 管道符,将 find 的输出传递给 xargsxargs- 将输入转换为命令行参数clang-format -i- 格式化并就地修改文件
Windows
for /r .- 递归遍历当前目录及子目录%i- 循环变量,代表找到的文件路径(*.c *.h)- 文件模式,匹配 .c 和 .h 文件do- 对每个找到的文件执行命令clang-format -i "%i"- 格式化文件,"%i"用引号包围以处理路径中的空格
常用变体命令
1. 格式化多种文件类型
Linux/Unix
# C/C++ 文件
find . -name "*.c" -o -name "*.cpp" -o -name "*.h" -o -name "*.hpp" | xargs clang-format -i
# 包含更多 C++ 文件类型
find . \( -name "*.c" -o -name "*.cpp" -o -name "*.cc" -o -name "*.cxx" -o -name "*.h" -o -name "*.hpp" -o -name "*.hxx" \) | xargs clang-format -i
Windows
# C/C++ 文件
for /r . %i in (*.c *.cpp *.h *.hpp) do clang-format -i "%i"
# 包含更多 C++ 文件类型
for /r . %i in (*.c *.cpp *.cc *.cxx *.h *.hpp *.hxx) do clang-format -i "%i"
2. 指定目录深度
Linux/Unix
# 只格式化当前目录(不包含子目录)
find . -maxdepth 1 -name "*.c" -o -name "*.h" | xargs clang-format -i
# 限制到 2 层目录
find . -maxdepth 2 -name "*.c" -o -name "*.h" | xargs clang-format -i
Windows
# 只格式化当前目录(不包含子目录)
for %i in (*.c *.h) do clang-format -i "%i"
# 限制到 2 层目录(需要更复杂的脚本)
@echo off
for /d %%d in (*) do (
for %%f in (%%d\*.c %%d\*.h) do clang-format -i "%%f"
)
for %i in (*.c *.h) do clang-format -i "%i"
3. 排除特定目录
Linux/Unix
# 排除 build 和 test 目录
find . -path "./build" -prune -o -path "./test" -prune -o -name "*.c" -o -name "*.h" | xargs clang-format -i
# 排除多个目录
find . \( -path "./build" -o -path "./test" -o -path "./third_party" \) -prune -o -name "*.c" -o -name "*.h" | xargs clang-format -i
Windows
# 排除特定目录的批处理脚本
@echo off
for /r . %i in (*.c *.h) do (
echo %i | findstr /v "build\\" | findstr /v "test\\" | findstr /v "third_party\\" >nul
if not errorlevel 1 clang-format -i "%i"
)
4. 预览格式化效果(不修改文件)
Linux/Unix
# 查看格式化后的内容
find . -name "*.c" -o -name "*.h" | xargs clang-format
# 查看与当前文件的差异
find . -name "*.c" -o -name "*.h" | xargs clang-format -output-replacements-xml
Windows
# 查看格式化后的内容
for /r . %i in (*.c *.h) do clang-format "%i"
# 查看与当前文件的差异
for /r . %i in (*.c *.h) do clang-format -output-replacements-xml "%i"
5. 指定样式文件
Linux/Unix
# 使用特定的样式文件
find . -name "*.c" -o -name "*.h" | xargs clang-format -i -style=file:.clang-format
# 使用预定义样式
find . -name "*.c" -o -name "*.h" | xargs clang-format -i -style=Google
Windows
# 使用特定的样式文件
for /r . %i in (*.c *.h) do clang-format -i -style=file:.clang-format "%i"
# 使用预定义样式
for /r . %i in (*.c *.h) do clang-format -i -style=Google "%i"
高级用法
1. 批量检查格式问题
Linux/Unix
# 检查哪些文件需要格式化
find . -name "*.c" -o -name "*.h" | xargs clang-format -output-replacements-xml | grep -c "replacement offset"
Windows
# 检查哪些文件需要格式化
@echo off
set count=0
for /r . %%i in (*.c *.h) do (
clang-format -output-replacements-xml "%%i" | findstr "replacement offset" >nul
if not errorlevel 1 set /a count+=1
)
echo 需要格式化的文件数量: %count%
2. 创建格式化脚本
Linux/Unix
#!/bin/bash
# format_code.sh
# 设置样式文件路径
STYLE_FILE=".clang-format"
# 检查样式文件是否存在
if [ ! -f "$STYLE_FILE" ]; then
echo "警告: 未找到 .clang-format 文件,将使用默认样式"
fi
# 格式化 C/C++ 文件
echo "开始格式化 C/C++ 文件..."
find . -name "*.c" -o -name "*.cpp" -o -name "*.h" -o -name "*.hpp" | \
xargs clang-format -i -style=file:$STYLE_FILE
echo "格式化完成!"
Windows
@echo off
REM format_code.bat
REM 设置样式文件路径
set STYLE_FILE=.clang-format
REM 检查样式文件是否存在
if not exist "%STYLE_FILE%" (
echo 警告: 未找到 .clang-format 文件,将使用默认样式
)
REM 格式化 C/C++ 文件
echo 开始格式化 C/C++ 文件...
for /r . %%i in (*.c *.cpp *.h *.hpp) do (
clang-format -i -style=file:%STYLE_FILE% "%%i"
)
echo 格式化完成!
pause
3. 与 Git 集成
Linux/Unix
# 只格式化已修改的文件
git diff --name-only --diff-filter=ACMR | grep -E '\.(c|cpp|h|hpp)$' | xargs clang-format -i
# 格式化暂存区的文件
git diff --cached --name-only | grep -E '\.(c|cpp|h|hpp)$' | xargs clang-format -i
Windows
# 只格式化已修改的文件
@echo off
for /f "delims=" %%i in ('git diff --name-only --diff-filter=ACMR') do (
echo %%i | findstr /r "\.c$ \.cpp$ \.h$ \.hpp$" >nul
if not errorlevel 1 clang-format -i "%%i"
)
# 格式化暂存区的文件
for /f "delims=" %%i in ('git diff --cached --name-only') do (
echo %%i | findstr /r "\.c$ \.cpp$ \.h$ \.hpp$" >nul
if not errorlevel 1 clang-format -i "%%i"
)
4. 并行处理(提高速度)
Linux/Unix
# 使用 GNU parallel(需要安装)
find . -name "*.c" -o -name "*.h" | parallel clang-format -i
# 或者使用 xargs 的 -P 参数
find . -name "*.c" -o -name "*.h" | xargs -P 4 clang-format -i
Windows
# Windows 下使用 PowerShell 并行处理
powershell -Command "Get-ChildItem -Recurse -Include *.c,*.h | ForEach-Object -Parallel { clang-format -i $_.FullName } -ThrottleLimit 4"
# 或者使用批处理的简单并行(需要多个批处理文件)
@echo off
start /b cmd /c "for /r . %%i in (*.c) do clang-format -i \"%%i\""
start /b cmd /c "for /r . %%i in (*.h) do clang-format -i \"%%i\""
注意事项
- 备份重要文件: 格式化会直接修改文件,建议先备份或使用版本控制
- 大项目处理: 对于大型项目,建议分批处理或使用并行处理
- 样式一致性: 确保团队使用相同的
.clang-format配置文件 - CI/CD 集成: 可以在持续集成中自动检查代码格式
故障排除
常见问题
- 命令未找到
Linux/Unix
# 检查 clang-format 是否在 PATH 中
which clang-format
# 或
where clang-format
Windows
# 检查 clang-format 是否在 PATH 中
where clang-format
# 或
clang-format --version
- 权限问题
Linux/Unix
# 确保有文件写入权限
chmod +w *.c *.h
Windows
# 确保文件不是只读的
attrib -r *.c *.h
# 或者以管理员身份运行命令提示符
- 文件路径包含空格
Linux/Unix
# 使用 -print0 和 -0 参数处理包含空格的文件名
find . -name "*.c" -o -name "*.h" -print0 | xargs -0 clang-format -i
Windows
# 在批处理脚本中使用双引号包围变量
for /r . %%i in (*.c *.h) do clang-format -i "%%i"
- 内存不足
Linux/Unix
# 分批处理
find . -name "*.c" -o -name "*.h" | split -l 100 - | while read batch; do
echo "$batch" | xargs clang-format -i
done
Windows
# 分批处理(每批处理 50 个文件)
@echo off
set count=0
for /r . %%i in (*.c *.h) do (
set /a count+=1
if !count! gtr 50 (
pause
set count=0
)
clang-format -i "%%i"
)
- Windows 特有问题
批处理变量延迟扩展
# 在批处理脚本开头添加
setlocal enabledelayedexpansion
路径分隔符问题
# 使用正斜杠或双反斜杠
for /r . %%i in (*.c *.h) do clang-format -i "%%i"
编码问题
# 设置控制台编码为 UTF-8
chcp 65001
相关工具
- astyle: 另一个代码格式化工具
- uncrustify: 高度可配置的代码格式化工具
- prettier: 主要用于前端代码格式化
- black: Python 代码格式化工具