서론
팀원들과 협업을 하다보면 인코딩에 대한 문제가 생기곤 한다. 주로 한국어로 주석을 하거나 출력을 할 때 문제가 생긴다. 물론, 프로젝트 이전에 논의해야할 주제 중 하나이지만 늦게 문제를 찾았을 때 인코딩 문제를 해결할 방안에 대해 알아보자.
인코딩( encoding )
인코딩은 정보나 데이터를 다른 형식으로 변환하는 프로세스로, 데이터 전송, 보안, 압축, 문자 인코딩, 영상 및 음성 처리, 데이터 형식 변환 등 다양한 목적으로 사용된다. 이를 통해 데이터를 정확하고 안전하게 효율적으로 다루고 전달할 수 있다. 이 블로그에서 다루는 문제는 문자 인코딩 문제를 다루고 있다.
인코딩 에러의 원인
팀원간에 협업에서 인코딩 에러의 원인은 주로 Mac, Window의 환경 차이에 있다. Mac은 UTF-8, Window는 ANSI을 보통 사용하기 때문에 인코딩 방식에 차이가 있어서 문자가 깨지는 현상이 발생한다.
Encoding Error의 해결방안
서로 나눠진 인코딩 방식을 통일하고 변경된 파일의 인코딩을 수정하고 앞으로 생성될 파일의 인코딩 방식을 통일시킨다.
메모장을 이용해 인코딩 변경
다음과 같이 파일을 메모장으로 열어 인코딩을 확인할 수 있다.(Win10) "파일 - 다른 이름으로 저장"을 클릭한다면 다음과 같이 인코딩을 변경할 수 있다.
.editorconfig 파일을 이용한 인코딩 통일
.editorconfig 파일은 Git과 같은 버전 관리 시스템을 사용하는 프로젝트에서 코드 스타일 및 서식을 관리하기 위한 설정 파일이다. 이 파일은 주로 다양한 개발자 및 팀원 간에 일관된 코드 스타일을 유지하고, 코드의 가독성을 향상시키기 위해 사용된다.
우선 프로젝트 내부에 .editorconfig 파일을 생성한다. (.editorconfig는 현재부터 하위 디텍토리까지 영향을 미치기 때문에 가장 상위에 위치하도록 하는 것이 좋다.) 이후 다음과 같은 코드를 입력한다.
root = true
[*]
charset = utf-8
.editorconfig의 추가적인 내용
.editorconfig 파일은 디렉토리에 여러 개 있을 수 있으며, 파일을 위에서 아래로 읽으면서 설정을 추가하고 재정의한다. 따라서 가장 가까운 .editorconfig 파일의 설정이 현재 편집 중인 파일에 우선적으로 적용된다. 설정은 .editorconfig 파일에서 현재 디렉토리부터 가져온 후, 상위 디렉토리의 .editorconfig 파일 등에서 가져오게 됩니다. 만약 코드베이스의 어떤 부분에도 해당 설정이 없다면, root=true를 사용하여 모든 상위 수준 .editorconfig 파일의 설정이 무시됨을 나타낼 수 있다. 이렇게 함으로써 설정의 범위를 제한할 수 있다.
- indent_style: 들여 쓰기를 'tab', 'space'중 어떤 걸로 할 것인지 설정
- indent_size: indent_style = space일 경우, 몇 칸 할 것인지 설정
- tab_width: indent_style = tab일 경우 width 설정 (기본적으로 indent_size 값을 따라가 거의 설정하지 않음)
- end_of_line: 'lf', 'cr', 'crlf'중 하나로 줄바꿈 설정
LF(Line Feed, \n): 커서를 다음 줄로 이동
CR(Carriage Return, \r): 현재 커서를 줄 바꿈 없이 가장 좌측으로 이동
CRLF: 현재 커서를 가장 좌측으로 이동하고 다음 줄로 이동
- charset: 'latin1', 'utf-8', 'utf-8-bom', 'utf-16be' or 'utf-16le' 중 하나로 문자 인코딩 방식 설정 (주로 'utf-8'로 설정)
- trim_trailing_whitespace: 'true'일 경우, 문자 앞의 공백을 제거
- insert_final_newline: 'true'일 경우, 파일을 저장할 때 새 줄로 끝남
- root: root 폴더의 파일에 설정하며, 'true'일 경우 .editorconfig 파일 검색을 중지
주섬주섬
- .editorconfig 파일은 특정 디렉토리 또는 하위 디렉토리에서 작동하는 코드 편집기 및 IDE(통합 개발 환경)에 적용된다. 이 파일에는 다음과 같은 내용이 포함될 수 있다. 프로젝트에 .editorconfig 파일을 추가하고 각 개발자의 코드 편집기나 IDE에서 .editorconfig 파일을 인식하도록 설정하면, 코드 스타일 관리가 용이해지며 협업이 효율적으로 이루어진다.
- 들여쓰기 스타일: 코드의 들여쓰기에 대한 규칙을 지정한다. 예를 들어, 탭(tab)을 사용할지, 스페이스(space)를 사용할지, 들여쓰기의 크기는 얼마인지 등을 설정할 수 있다.
- 줄 바꿈: 줄 바꿈 문자(개행 문자)의 스타일을 지정한다. 유닉스 스타일(LF) 또는 윈도우 스타일(CRLF)로 설정할 수 있다.
- 문자 인코딩: 파일의 문자 인코딩을 지정한다. 주로 UTF-8이나 다른 인코딩을 설정할 수 있다.
- 파일 확장자: 특정 파일 확장자에 대한 스타일 설정을 지정할 수 있다. 예를 들어, .js 파일에 대한 들여쓰기 스타일을 설정할 수 있다.
- 예외 설정: 특정 파일 또는 디렉토리에 대한 예외 설정을 지정할 수 있다.
참고
아래 더보기는 Unity 프로젝트에 쓴 .editorconfig 파일의 내용이다.
# 상위 디렉터리에서 .editorconfig 설정을 상속하려면 아래 행을 제거하세요.
root = true
# C# 파일
[*.cs]
#### 코어 EditorConfig 옵션 ####
# 들여쓰기 및 간격
indent_size = 4
indent_style = space
tab_width = 4
# 새 줄 기본 설정
end_of_line = crlf
insert_final_newline = false
#### .NET 코딩 규칙 ####
# Using 구성
dotnet_separate_import_directive_groups = false
dotnet_sort_system_directives_first = false
file_header_template = unset
# this. 및 Me. 기본 설정
dotnet_style_qualification_for_event = false
dotnet_style_qualification_for_field = false
dotnet_style_qualification_for_method = false
dotnet_style_qualification_for_property = false
# 언어 키워드 및 BCL 형식 기본 설정
dotnet_style_predefined_type_for_locals_parameters_members = true
dotnet_style_predefined_type_for_member_access = true
# 괄호 기본 설정
dotnet_style_parentheses_in_arithmetic_binary_operators = always_for_clarity
dotnet_style_parentheses_in_other_binary_operators = always_for_clarity
dotnet_style_parentheses_in_other_operators = never_if_unnecessary
dotnet_style_parentheses_in_relational_binary_operators = always_for_clarity
# 한정자 기본 설정
dotnet_style_require_accessibility_modifiers = for_non_interface_members
# 식 수준 기본 설정
dotnet_style_coalesce_expression = true
dotnet_style_collection_initializer = true
dotnet_style_explicit_tuple_names = true
dotnet_style_namespace_match_folder = true
dotnet_style_null_propagation = true
dotnet_style_object_initializer = true
dotnet_style_operator_placement_when_wrapping = beginning_of_line
dotnet_style_prefer_auto_properties = true
dotnet_style_prefer_compound_assignment = true
dotnet_style_prefer_conditional_expression_over_assignment = true
dotnet_style_prefer_conditional_expression_over_return = true
dotnet_style_prefer_foreach_explicit_cast_in_source = when_strongly_typed
dotnet_style_prefer_inferred_anonymous_type_member_names = true
dotnet_style_prefer_inferred_tuple_names = true
dotnet_style_prefer_is_null_check_over_reference_equality_method = true
dotnet_style_prefer_simplified_boolean_expressions = true
dotnet_style_prefer_simplified_interpolation = true
# 필드 기본 설정
dotnet_style_readonly_field = true
# 매개 변수 기본 설정
dotnet_code_quality_unused_parameters = all
# 비표시 오류(Suppression) 기본 설정
dotnet_remove_unnecessary_suppression_exclusions = none
# 새 줄 기본 설정
dotnet_style_allow_multiple_blank_lines_experimental = true
dotnet_style_allow_statement_immediately_after_block_experimental = true
#### C# 코딩 규칙 ####
# var 기본 설정
csharp_style_var_elsewhere = false
csharp_style_var_for_built_in_types = false
csharp_style_var_when_type_is_apparent = false
# 식 본문 멤버
csharp_style_expression_bodied_accessors = true
csharp_style_expression_bodied_constructors = false
csharp_style_expression_bodied_indexers = true
csharp_style_expression_bodied_lambdas = true
csharp_style_expression_bodied_local_functions = false
csharp_style_expression_bodied_methods = false
csharp_style_expression_bodied_operators = false
csharp_style_expression_bodied_properties = true
# 패턴 일치 기본 설정
csharp_style_pattern_matching_over_as_with_null_check = true
csharp_style_pattern_matching_over_is_with_cast_check = true
csharp_style_prefer_extended_property_pattern = true
csharp_style_prefer_not_pattern = true
csharp_style_prefer_pattern_matching = true
csharp_style_prefer_switch_expression = true
# Null 검사 기본 설정
csharp_style_conditional_delegate_call = true
# 한정자 기본 설정
csharp_prefer_static_local_function = true
csharp_preferred_modifier_order = public,private,protected,internal,file,static,extern,new,virtual,abstract,sealed,override,readonly,unsafe,required,volatile,async
csharp_style_prefer_readonly_struct = true
# 코드 블록 기본 설정
csharp_prefer_braces = true
csharp_prefer_simple_using_statement = true
csharp_style_namespace_declarations = block_scoped
csharp_style_prefer_method_group_conversion = true
csharp_style_prefer_top_level_statements = true
# 식 수준 기본 설정
csharp_prefer_simple_default_expression = true
csharp_style_deconstructed_variable_declaration = true
csharp_style_implicit_object_creation_when_type_is_apparent = true
csharp_style_inlined_variable_declaration = true
csharp_style_prefer_index_operator = true
csharp_style_prefer_local_over_anonymous_function = true
csharp_style_prefer_null_check_over_type_check = true
csharp_style_prefer_range_operator = true
csharp_style_prefer_tuple_swap = true
csharp_style_prefer_utf8_string_literals = true
csharp_style_throw_expression = true
csharp_style_unused_value_assignment_preference = discard_variable
csharp_style_unused_value_expression_statement_preference = discard_variable
# 'using' 지시문 기본 설정
csharp_using_directive_placement = outside_namespace
# 새 줄 기본 설정
csharp_style_allow_blank_line_after_colon_in_constructor_initializer_experimental = true
csharp_style_allow_blank_lines_between_consecutive_braces_experimental = true
csharp_style_allow_embedded_statements_on_same_line_experimental = true
#### C# 서식 설정 규칙 ####
# 새 줄 기본 설정
csharp_new_line_before_catch = true
csharp_new_line_before_else = true
csharp_new_line_before_finally = true
csharp_new_line_before_members_in_anonymous_types = true
csharp_new_line_before_members_in_object_initializers = true
csharp_new_line_before_open_brace = all
csharp_new_line_between_query_expression_clauses = true
# 들여쓰기 기본 설정
csharp_indent_block_contents = true
csharp_indent_braces = false
csharp_indent_case_contents = true
csharp_indent_case_contents_when_block = true
csharp_indent_labels = one_less_than_current
csharp_indent_switch_labels = true
# 공간 기본 설정
csharp_space_after_cast = false
csharp_space_after_colon_in_inheritance_clause = true
csharp_space_after_comma = true
csharp_space_after_dot = false
csharp_space_after_keywords_in_control_flow_statements = true
csharp_space_after_semicolon_in_for_statement = true
csharp_space_around_binary_operators = before_and_after
csharp_space_around_declaration_statements = false
csharp_space_before_colon_in_inheritance_clause = true
csharp_space_before_comma = false
csharp_space_before_dot = false
csharp_space_before_open_square_brackets = false
csharp_space_before_semicolon_in_for_statement = false
csharp_space_between_empty_square_brackets = false
csharp_space_between_method_call_empty_parameter_list_parentheses = false
csharp_space_between_method_call_name_and_opening_parenthesis = false
csharp_space_between_method_call_parameter_list_parentheses = false
csharp_space_between_method_declaration_empty_parameter_list_parentheses = false
csharp_space_between_method_declaration_name_and_open_parenthesis = false
csharp_space_between_method_declaration_parameter_list_parentheses = false
csharp_space_between_parentheses = false
csharp_space_between_square_brackets = false
# 기본 설정 래핑
csharp_preserve_single_line_blocks = true
csharp_preserve_single_line_statements = true
#### 명명 스타일 ####
# 명명 규칙
dotnet_naming_rule.interface_should_be_begins_with_i.severity = suggestion
dotnet_naming_rule.interface_should_be_begins_with_i.symbols = interface
dotnet_naming_rule.interface_should_be_begins_with_i.style = begins_with_i
dotnet_naming_rule.types_should_be_pascal_case.severity = suggestion
dotnet_naming_rule.types_should_be_pascal_case.symbols = types
dotnet_naming_rule.types_should_be_pascal_case.style = pascal_case
dotnet_naming_rule.non_field_members_should_be_pascal_case.severity = suggestion
dotnet_naming_rule.non_field_members_should_be_pascal_case.symbols = non_field_members
dotnet_naming_rule.non_field_members_should_be_pascal_case.style = pascal_case
# 기호 사양
dotnet_naming_symbols.interface.applicable_kinds = interface
dotnet_naming_symbols.interface.applicable_accessibilities = public, internal, private, protected, protected_internal, private_protected
dotnet_naming_symbols.interface.required_modifiers =
dotnet_naming_symbols.types.applicable_kinds = class, struct, interface, enum
dotnet_naming_symbols.types.applicable_accessibilities = public, internal, private, protected, protected_internal, private_protected
dotnet_naming_symbols.types.required_modifiers =
dotnet_naming_symbols.non_field_members.applicable_kinds = property, event, method
dotnet_naming_symbols.non_field_members.applicable_accessibilities = public, internal, private, protected, protected_internal, private_protected
dotnet_naming_symbols.non_field_members.required_modifiers =
# 명명 스타일
dotnet_naming_style.pascal_case.required_prefix =
dotnet_naming_style.pascal_case.required_suffix =
dotnet_naming_style.pascal_case.word_separator =
dotnet_naming_style.pascal_case.capitalization = pascal_case
dotnet_naming_style.begins_with_i.required_prefix = I
dotnet_naming_style.begins_with_i.required_suffix =
dotnet_naming_style.begins_with_i.word_separator =
dotnet_naming_style.begins_with_i.capitalization = pascal_case
[*]
charset = utf-8
'VCS > 협업' 카테고리의 다른 글
VCS 프로젝트 브랜치 전략 (1) | 2024.07.14 |
---|---|
게임 팀 프로젝트 기획부터 개발 (0) | 2023.04.18 |
댓글