問題說明
在用c語(yǔ)言進(jìn)行開發(fā)的時(shí)候, 因?yàn)槭嵌嗳藚f(xié)同開發(fā), 經(jīng)常會(huì)遇到自己的代碼和別人的代碼格式不一致的問題, 于是就想配置vscode自動(dòng)對(duì)代碼進(jìn)行格式化, 經(jīng)過上網(wǎng)搜索確定使用clang-format, 但是修改.clang-format配置文件, 卻一直無(wú)法生效, 今天終于找到了原因.
解決過程
其實(shí)網(wǎng)上的教程都沒有問題, 首先是安裝cpptools插件, 它默認(rèn)會(huì)安裝LLVM(帶有clang), 我的默認(rèn)路徑是"C:\Users\DR\.vscode\extensions\ms-vscode.cpptools-0.26.3-insiders2\LLVM\bin\clang-format.exe", 然后在設(shè)置里面配置 C_Cpp:Clang_format_style為file, 它的意思是說如果工程里面有.clang-format配置文件的話, 就按照配置文件的內(nèi)容來(lái)進(jìn)行格式化, 如果沒有這個(gè)文件, 那么就按照C_Cpp:Clang_format_fallback Style進(jìn)行格式化.這樣配置完之后就可以自己修改.clang-format文件進(jìn)行配置了(如果沒有可以先通過clang-format -style=llvm -dump-config > .clang-format命令生成一個(gè)模版), 只不過在整個(gè)過程中有兩點(diǎn)注意事項(xiàng):
- .clang-format需要放到你的工程目錄下. 就是說每個(gè)工程都要有一個(gè).clang-format文件來(lái)自定義你的格式. 我也曾想有沒有方法可以只用一個(gè).clang-format, 所有工程都適用, 但是搜遍了網(wǎng)絡(luò)發(fā)現(xiàn)并沒有好的辦法, 官方就不支持這個(gè).(不過也有網(wǎng)友通過自定義clang-format.exe來(lái)實(shí)現(xiàn), 我沒用就不說了).
- .clang-format中不能有中文. 我之前不知道從哪里找到一個(gè)帶有中文注釋的.clang-format文件. 解釋的很詳細(xì), 讓我明白每個(gè)參數(shù)都是用來(lái)配置什么內(nèi)容的, 所以就直接拷貝過來(lái)了, 結(jié)果放到自己的工程里死活不好用, 后來(lái)我又重新生成了一個(gè)標(biāo)準(zhǔn)文件, 發(fā)現(xiàn)可用, 才意識(shí)到原來(lái)是不能有中文, 又確認(rèn)了一遍確實(shí)是這個(gè)原因, 所以大家在用的時(shí)候要注意這個(gè)問題, 可以參考注釋進(jìn)行配置, 但是文件中不要出現(xiàn)中文哦.
下面貼一下我的那份帶注釋的.clang-format, 大家可以參考但不要直接復(fù)制哦, 復(fù)制的話要?jiǎng)h除中文注釋再用:
---
# 語(yǔ)言: None, Cpp, Java, JavaScript, ObjC, Proto, TableGen, TextProto
Language: Cpp
# BasedOnStyle: LLVM
# 訪問說明符(public、private等)的偏移
AccessModifierOffset: -4
# 開括號(hào)(開圓括號(hào)、開尖括號(hào)、開方括號(hào))后的對(duì)齊: Align, DontAlign, AlwaysBreak(總是在開括號(hào)后換行)
AlignAfterOpenBracket: Align
# 連續(xù)賦值時(shí),對(duì)齊所有等號(hào)
AlignConsecutiveAssignments: true
# 連續(xù)聲明時(shí),對(duì)齊所有聲明的變量名
AlignConsecutiveDeclarations: true
AlignEscapedNewlines: Right
# 左對(duì)齊逃脫換行(使用反斜杠換行)的反斜杠
#AlignEscapedNewlinesLeft: true
# 水平對(duì)齊二元和三元表達(dá)式的操作數(shù)
AlignOperands: true
# 對(duì)齊連續(xù)的尾隨的注釋
AlignTrailingComments: true
# 允許函數(shù)聲明的所有參數(shù)在放在下一行
AllowAllParametersOfDeclarationOnNextLine: false
# 允許短的塊放在同一行
AllowShortBlocksOnASingleLine: true
# 允許短的case標(biāo)簽放在同一行
AllowShortCaseLabelsOnASingleLine: true
# 允許短的函數(shù)放在同一行: None, InlineOnly(定義在類中), Empty(空函數(shù)), Inline(定義在類中,空函數(shù)), All
AllowShortFunctionsOnASingleLine: Empty
# 允許短的if語(yǔ)句保持在同一行
AllowShortIfStatementsOnASingleLine: false
# 允許短的循環(huán)保持在同一行
AllowShortLoopsOnASingleLine: false
# 總是在定義返回類型后換行(deprecated)
AlwaysBreakAfterDefinitionReturnType: None
# 總是在返回類型后換行: None, All, TopLevel(頂級(jí)函數(shù),不包括在類中的函數(shù)),
# AllDefinitions(所有的定義,不包括聲明), TopLevelDefinitions(所有的頂級(jí)函數(shù)的定義)
AlwaysBreakAfterReturnType: None
# 總是在多行string字面量前換行
AlwaysBreakBeforeMultilineStrings: false
# 總是在template聲明后換行
AlwaysBreakTemplateDeclarations: false
# false表示函數(shù)實(shí)參要么都在同一行,要么都各自一行
BinPackArguments: true
# false表示所有形參要么都在同一行,要么都各自一行
BinPackParameters: false
# 大括號(hào)換行,只有當(dāng)BreakBeforeBraces設(shè)置為Custom時(shí)才有效
BraceWrapping:
# class定義后面
AfterClass: false
# 控制語(yǔ)句后面
AfterControlStatement: true
# enum定義后面
AfterEnum: true
# 函數(shù)定義后面
AfterFunction: true
# 命名空間定義后面
AfterNamespace: false
# ObjC定義后面
AfterObjCDeclaration: false
# struct定義后面
AfterStruct: true
# union定義后面
AfterUnion: true
AfterExternBlock: false
# catch之前
BeforeCatch: true
# else之前
BeforeElse: true
# 縮進(jìn)大括號(hào)
IndentBraces: true
SplitEmptyFunction: false
SplitEmptyRecord: false
SplitEmptyNamespace: false
# 在二元運(yùn)算符前換行: None(在操作符后換行), NonAssignment(在非賦值的操作符前換行), All(在操作符前換行)
BreakBeforeBinaryOperators: None
# 在大括號(hào)前換行: Attach(始終將大括號(hào)附加到周圍的上下文), Linux(除函數(shù)、命名空間和類定義,與Attach類似),
# Mozilla(除枚舉、函數(shù)、記錄定義,與Attach類似), Stroustrup(除函數(shù)定義、catch、else,與Attach類似),
# Allman(總是在大括號(hào)前換行), GNU(總是在大括號(hào)前換行,并對(duì)于控制語(yǔ)句的大括號(hào)增加額外的縮進(jìn)), WebKit(在函數(shù)前換行), Custom
# 注:這里認(rèn)為語(yǔ)句塊也屬于函數(shù)
BreakBeforeBraces: Custom
# 在三元運(yùn)算符前換行
BreakBeforeTernaryOperators: false
# 在構(gòu)造函數(shù)的初始化列表的逗號(hào)前換行
BreakConstructorInitializersBeforeComma: false
BreakConstructorInitializers: BeforeColon
# 每行字符的限制,0表示沒有限制
ColumnLimit: 80
# 描述具有特殊意義的注釋的正則表達(dá)式,它不應(yīng)該被分割為多行或以其它方式改變
CommentPragmas: '^ IWYU pragma:'
CompactNamespaces: false
# 構(gòu)造函數(shù)的初始化列表要么都在同一行,要么都各自一行
ConstructorInitializerAllOnOneLineOrOnePerLine: false
# 構(gòu)造函數(shù)的初始化列表的縮進(jìn)寬度
ConstructorInitializerIndentWidth: 4
# 延續(xù)的行的縮進(jìn)寬度
ContinuationIndentWidth: 4
# 去除C++11的列表初始化的大括號(hào){后和}前的空格
Cpp11BracedListStyle: true
# 繼承最常用的指針和引用的對(duì)齊方式
DerivePointerAlignment: true
# 關(guān)閉格式化
DisableFormat: false
# 自動(dòng)檢測(cè)函數(shù)的調(diào)用和定義是否被格式為每行一個(gè)參數(shù)(Experimental)
ExperimentalAutoDetectBinPacking: false
# 需要被解讀為foreach循環(huán)而不是函數(shù)調(diào)用的宏
ForEachMacros: [ foreach, Q_FOREACH, BOOST_FOREACH ]
# 對(duì)#include進(jìn)行排序,匹配了某正則表達(dá)式的#include擁有對(duì)應(yīng)的優(yōu)先級(jí),匹配不到的則默認(rèn)優(yōu)先級(jí)為INT_MAX(優(yōu)先級(jí)越小排序越靠前),
# 可以定義負(fù)數(shù)優(yōu)先級(jí)從而保證某些#include永遠(yuǎn)在最前面
IncludeCategories:
- Regex: '^"(llvm|llvm-c|clang|clang-c)/'
Priority: 2
- Regex: '^(<|"(gtest|isl|json)/)'
Priority: 3
- Regex: '.*'
Priority: 1
# 縮進(jìn)case標(biāo)簽
IndentCaseLabels: true
IndentPPDirectives: AfterHash
# 縮進(jìn)寬度
IndentWidth: 4
# 函數(shù)返回類型換行時(shí),縮進(jìn)函數(shù)聲明或函數(shù)定義的函數(shù)名
IndentWrappedFunctionNames: false
# 保留在塊開始處的空行
KeepEmptyLinesAtTheStartOfBlocks: false
# 開始一個(gè)塊的宏的正則表達(dá)式
MacroBlockBegin: ''
# 結(jié)束一個(gè)塊的宏的正則表達(dá)式
MacroBlockEnd: ''
# 連續(xù)空行的最大數(shù)量
MaxEmptyLinesToKeep: 4
# 命名空間的縮進(jìn): None, Inner(縮進(jìn)嵌套的命名空間中的內(nèi)容), All
NamespaceIndentation: Inner
# 使用ObjC塊時(shí)縮進(jìn)寬度
ObjCBlockIndentWidth: 4
# 在ObjC的@property后添加一個(gè)空格
ObjCSpaceAfterProperty: false
# 在ObjC的protocol列表前添加一個(gè)空格
ObjCSpaceBeforeProtocolList: true
# 在call(后對(duì)函數(shù)調(diào)用換行的penalty
PenaltyBreakBeforeFirstCallParameter: 19
# 在一個(gè)注釋中引入換行的penalty
PenaltyBreakComment: 300
# 第一次在<<前換行的penalty
PenaltyBreakFirstLessLess: 120
# 在一個(gè)字符串字面量中引入換行的penalty
PenaltyBreakString: 1000
# 對(duì)于每個(gè)在行字符數(shù)限制之外的字符的penalty
PenaltyExcessCharacter: 1000000
# 將函數(shù)的返回類型放到它自己的行的penalty
PenaltyReturnTypeOnItsOwnLine: 60
# 指針和引用的對(duì)齊: Left, Right, Middle
PointerAlignment: Left
# 允許重新排版注釋
ReflowComments: true
# 允許排序#include
SortIncludes: true
# 在C風(fēng)格類型轉(zhuǎn)換后添加空格
SpaceAfterCStyleCast: false
SpaceAfterTemplateKeyword: true
# 在賦值運(yùn)算符之前添加空格
SpaceBeforeAssignmentOperators: true
# 開圓括號(hào)之前添加一個(gè)空格: Never, ControlStatements, Always
SpaceBeforeParens: ControlStatements
# 在空的圓括號(hào)中添加空格
SpaceInEmptyParentheses: true
# 在尾隨的評(píng)論前添加的空格數(shù)(只適用于//)
SpacesBeforeTrailingComments: 2
# 在尖括號(hào)的<后和>前添加空格
SpacesInAngles: false
# 在容器(ObjC和JavaScript的數(shù)組和字典等)字面量中添加空格
SpacesInContainerLiterals: false
# 在C風(fēng)格類型轉(zhuǎn)換的括號(hào)中添加空格
SpacesInCStyleCastParentheses: true
# 在圓括號(hào)的(后和)前添加空格
SpacesInParentheses: true
# 在方括號(hào)的[后和]前添加空格,lamda表達(dá)式和未指明大小的數(shù)組的聲明不受影響
SpacesInSquareBrackets: true
# 標(biāo)準(zhǔn): Cpp03, Cpp11, Auto
Standard: Cpp11
# tab寬度
TabWidth: 4
# 使用tab字符: Never, ForIndentation, ForContinuationAndIndentation, Always
UseTab: Always