UTF-8格式大统一:转码高效指南,彻底解决文件编码乱码问题!

文章目录

    • 1 背景说明
    • 2 统一的好处
    • 3 对增量代码怎么进行统一
    • 4 对存量代码怎么进行统一
      • 4.1 指定单一文件夹,对里面的 .h .cpp 文件全转换
      • 4.2 指定单一文件夹,对里面的.h .cpp文件按需转换
      • 4.3 指定多文件夹,对里面的.h .cpp文件全部转换
      • 4.4 指定多文件夹,对里面的.h .cpp文件按需转换
    • 总结

1 背景说明

你是否遇到过,在项目开发过程中,项目组成员编码完成后,保存的文件格式五花八门,在集成编译的过程中各种报错,结果定位过程中,发现是编码格式的问题;亦或是代码跨平台迁移时,由于编码格式的不统一,编译器又是报各种问题;亦或是用 BeyondCompare 去对比代码时,由于文件格式的不同,直接报显示错误,或是代码乱码。

依此种种,总是让人抓狂,而废了老大劲定位之后,大多都指向文件格式不统一的问题,有顿时感觉这么小的问题,竟然还犯,又像泄了气的气球。痛定思痛之后,下次还是遇到,真是无语。

那么怎么对文件格式进行统一呢,就是本文要展开的话题,甭管它是后续增量的,还是代码库中已有存量的,从全方位的角度来对文件格式问题进行处理。

2 统一的好处

我们先来具体的看下,文件格式不统一,在编码过程中究竟会导致哪些问题。

笔者在查找了相关资料之后,总结会有以下几类影响:

  • 字符显示错误
  • 字符串处理错误
  • 跨平台兼容问题
  • 开发工具和版本控制系统的兼容问题等。

那么对文件格式统一为 UTF-8 格式又有哪些好处呢:

  • 跨平台一致性:UTF-8是一种广泛支持的编码格式,适用于多种操作系统和开发环境。通过统一编码格式,可以确保代码在不同平台之间具有更好的兼容性,无论是在Windows、Linux还是MacOS上,文件都能被正确解析和显示。

  • 国际化支持:UTF-8支持表示全世界绝大多数的字符,这为多语言开发和国际化项目提供了便利。如果项目中涉及到多种语言,使用UTF-8可以避免编码转换造成的乱码问题。

  • 简化开发流程:在团队开发环境中,不同开发者可能使用不同的操作系统和工具。如果不统一文件的编码格式,可能会因为编码不兼容而导致代码合作时出现问题,比如代码审查时出现乱码。统一使用UTF-8可以减少这类问题,简化版本控制和代码合作流程。

  • 避免编码错误:不统一编码格式可能会导致编译器或解释器错误理解源代码,特别是当代码文件包含非ASCII字符时。这可能会导致编译错误或运行时错误,尤其是在字符串处理和字符编码转换时更加明显。

  • 标准化推荐:许多现代编程语言和标准化组织都推荐或要求使用UTF-8编码。例如,Python 3将UTF-8作为源代码文件的默认编码,HTML5明确规定使用UTF-8。遵循这些标准和最佳实践有利于提高代码的可维护性和可读性。

好的,讲了这么多背景知识,至少从思想上,我们统一了,对文件格式进行 UTF-8 统一,在项目开发过程中,还是有很明显的好处的。

那么具体而言,我们该怎么做呢?

3 对增量代码怎么进行统一

对新增的文件,我们采用统一编译器配置的措施来进行干预。在项目组中进行开发,统一开发的 IDE 工具及其配置是必不可少的。

在此我以 VS2017 来进行举例:

对新增文件,可以通过配置模板文件形式进行设置:

C:\Program Files (x86)\Microsoft Visual Studio\2017\Community\Common7\IDE\VC\vcprojectitems 里放 hfile.hnewc++file.cpp 两个文件,有些人路径可能为:C:\Program Files (x86)\Microsoft Visual Studio\2017\Professional\Common7\IDE\VC\vcprojectitems 目录。

hfile.hnewc++file.cpp 模板文件为自己配置的已设置好格式的UTF-8格式的文件模板。

在 VS 中配置好这些之后,在工程项目中中新增加文件(“解决方案 -》 添加 -》 新建项”)的时候,VS就会按这两个模板文件的编码来保存文件了。

另外,模板文件也可以加上版权声明,就不需要我们每次新建文件时,手动加版权声明了。

在这里插入图片描述

4 对存量代码怎么进行统一

对于存量文件的情况,有四种场景,我们来一一看下相应的解决方案。

4.1 指定单一文件夹,对里面的 .h .cpp 文件全转换

import chardet
import os
import codecsdef get_encoding(file_name):f = open(file_name, 'rb')encoding = chardet.detect(f.read())['encoding']return encodingdef write(file_name, content):with codecs.open(file_name, 'w', 'utf-8') as f:f.write(content)def read(file_name, encoding):with codecs.open(file_name, 'r', encoding) as f:return f.read()def convert(src_file, dst_file):content = Nonetry:encoding = get_encoding(src_file)content = read(src_file, encoding)except OSError:print("something wrong: %s" % src_file)finally:write(dst_file, content)#print("Done")def convert_dir(src_dir, dst_dir, sub_dir, file_prefixes=[]):src_prj_dir = os.path.join(src_dir, sub_dir)for root, dirs, files in os.walk(src_prj_dir):dst_root = root.replace(src_dir, dst_dir)for f in files:if f.endswith('.h') or f.endswith('.cpp'):if file_prefixes:to_parse = Falsefor p in file_prefixes:if f.startswith(p):to_parse = Truebreakif not to_parse:continueos.makedirs(dst_root, exist_ok=True)src_file = os.path.join(root, f)dst_file = os.path.join(dst_root, f)convert(src_file, dst_file)if __name__ == '__main__':src_dir = 'D:/ProjectRootDir/AModule/source'  # 源文件夹根路径dst_dir = 'F:/Python/Src/result'  # 转换成utf8 后目的路径convert_dir(src_dir, dst_dir, 'include')  # 对源文件夹下 include 目录扫描

4.2 指定单一文件夹,对里面的.h .cpp文件按需转换

import chardet
import os
import codecsdef get_encoding(file_name):f = open(file_name, 'rb')encoding = chardet.detect(f.read())['encoding']return encodingdef write(file_name, content):with codecs.open(file_name, 'w', 'utf-8') as f:f.write(content)def read(file_name, encoding):with codecs.open(file_name, 'r', encoding) as f:return f.read()def convert(src_file, dst_file):content = Nonetry:encoding = get_encoding(src_file)content = read(src_file, encoding)except OSError:print("something wrong: %s" % src_file)finally:write(dst_file, content)#print("Done")def convert_dir(src_dir, dst_dir, sub_dir, file_prefixes=[]):src_prj_dir = os.path.join(src_dir, sub_dir)for root, dirs, files in os.walk(src_prj_dir):dst_root = root.replace(src_dir, dst_dir)for f in files:if f.endswith('.h') or f.endswith('.cpp'):if file_prefixes:to_parse = Falsefor p in file_prefixes:if f.startswith(p):to_parse = Truebreakif not to_parse:continueos.makedirs(dst_root, exist_ok=True)src_file = os.path.join(root, f)dst_file = os.path.join(dst_root, f)convert(src_file, dst_file)if __name__ == '__main__':src_dir = 'D:/ProjectRootDir/AModule/source'  # 源文件夹根路径dst_dir = 'F:/Python/Src/result'  # 转换成utf8 后目的路径prefixes = ['prop_', 'resource_', 'widgets_']  # 选定带特定前缀的文件进行转换convert_dir(src_dir, dst_dir, 'include', prefixes)  # 对源文件夹下 include 目录中带特定前缀的文件进行转换

4.3 指定多文件夹,对里面的.h .cpp文件全部转换

import chardet
import os
import codecsdef get_encoding(file_name):f = open(file_name, 'rb')encoding = chardet.detect(f.read())['encoding']return encodingdef write(file_name, content):with codecs.open(file_name, 'w', 'utf-8') as f:f.write(content)def read(file_name, encoding):with codecs.open(file_name, 'r', encoding) as f:return f.read()def convert(src_file, dst_file):content = Nonetry:encoding = get_encoding(src_file)content = read(src_file, encoding)except OSError:print("something wrong: %s" % src_file)finally:write(dst_file, content)#print("Done")def convert_dir(src_dir, dst_dir, sub_dir, file_prefixes=[]):src_prj_dir = os.path.join(src_dir, sub_dir)for root, dirs, files in os.walk(src_prj_dir):dst_root = root.replace(src_dir, dst_dir)for f in files:if f.endswith('.h') or f.endswith('.cpp'):if file_prefixes:to_parse = Falsefor p in file_prefixes:if f.startswith(p):to_parse = Truebreakif not to_parse:continueos.makedirs(dst_root, exist_ok=True)src_file = os.path.join(root, f)dst_file = os.path.join(dst_root, f)convert(src_file, dst_file)if __name__ == '__main__':src_dir = 'D:/ProjectRootDir/AModule/source'  # 源文件夹根路径dst_dir = 'F:/Python/Src/result'  # 转换成utf8 后目的路径prjs = ['config', 'gui', 'rs/include', 'rs/ResourceSystem']for p in prjs:convert_dir(src_dir, dst_dir, p)  # 对源文件夹下config、gui等子文件夹下的文件进行转换

4.4 指定多文件夹,对里面的.h .cpp文件按需转换

import chardet
import os
import codecsdef get_encoding(file_name):f = open(file_name, 'rb')encoding = chardet.detect(f.read())['encoding']return encodingdef write(file_name, content):with codecs.open(file_name, 'w', 'utf-8') as f:f.write(content)def read(file_name, encoding):with codecs.open(file_name, 'r', encoding) as f:return f.read()def convert(src_file, dst_file):content = Nonetry:encoding = get_encoding(src_file)content = read(src_file, encoding)except OSError:print("something wrong: %s" % src_file)finally:write(dst_file, content)#print("Done")def convert_dir(src_dir, dst_dir, sub_dir, file_prefixes=[]):src_prj_dir = os.path.join(src_dir, sub_dir)for root, dirs, files in os.walk(src_prj_dir):dst_root = root.replace(src_dir, dst_dir)for f in files:if f.endswith('.h') or f.endswith('.cpp'):if file_prefixes:to_parse = Falsefor p in file_prefixes:if f.startswith(p):to_parse = Truebreakif not to_parse:continueos.makedirs(dst_root, exist_ok=True)src_file = os.path.join(root, f)dst_file = os.path.join(dst_root, f)convert(src_file, dst_file)if __name__ == '__main__':src_dir = 'D:/ProjectRootDir/AModule/source'  # 源文件夹根路径dst_dir = 'F:/Python/Src/result'  # 转换成utf8 后目的路径# parse A includeprefixes = ['gui_', 'prop_', 'resource_', 'widgets_']convert_dir(src_dir, dst_dir, 'A', prefixes)  # 对源文件夹下 A 目录中带特定前缀的文件进行转换扫描# parse project group or projectprjs = ['config', 'gui', 'rs/include', 'rs/ResourceSystem']for p in prjs:convert_dir(src_dir, dst_dir, p)  # 对源文件夹下config、gui等子文件夹下的文件进行转换# parse some include fileconvert_dir(src_dir, dst_dir, 'C/include', ['pm_property', 'prop_'])  # 对指定目录下的指定前缀文件进行转换convert_dir(src_dir, dst_dir, 'D/include', ['ply_property', 'db_property'])

总结

上述的方法基本上能覆盖到整个开发流程中,UTF8文件统一的方方面面,大家在遇到实际问题情况下,可以按需取用。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/333204.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

用数据,简单点!奇点云2024 StartDT Day数智科技大会,直播见

在充满挑战的2024,企业如何以最小化的资源投入和试错成本,挖掘新的增长机会,实现确定性发展? “简单点”是当前商业环境的应对策略,也是奇点云2024 StartDT Day的核心理念。 5月28日,由奇点云主办的2024 S…

RPA机器人流程自动化如何优化人力资源工作流程

人力资源部门在支持员工和改善整体工作环节方面扮演着至关重要的角色,但是在人资管理的日常工作中,充斥着大量基于规则的重复性任务,例如简历筛选、面试安排、员工数据管理、培训管理、绩效管理等,这些任务通常需要工作人员花费大…

Hive课程文档

基本语法 库操作 Hive和MySQL类似,提供了针对database的操作。 1)创建库: create database demo; 注意,每一个database在HDFS上都会对应一个目录,如果不指定,那么默认是放在/user/hive/warehouse/下。在Hive中&am…

消息回复及时,客户不流失!这个微信自动回复设置快快码住!

你是不是也遇到过由于回复不及时,导致客户流失的情况发生?或是好友申请太多,来不及通过? 别担心,试试个微管理系统,让你实现自动回复,提高回复效率! 1、自动通过好友 当有新的好友…

5.23 Linux中超时检测方式+模拟面试

1.IO多路复用的原理? IO多路复用使得一个或少量线程资源处理多个连接的IO事件的技术。对于要处理的多个阻塞的IO操作,建立集合并存储它们的文件描述符,利用单个阻塞函数去监控集合中文件描述符事件到达的情况,(如果到…

Python 全栈体系【四阶】(五十三)

第五章 深度学习 十二、光学字符识别(OCR) 2. 文字检测技术 2.3 DB(2020) DB全称是Differentiable Binarization(可微分二值化),是近年提出的利用图像分割方法进行文字检测的模型。前文所提…

如何评价 OpenAI 最新发布支持实时语音对话的模型GPT-4o?OpenAI发完GTP-4o,国内大模型行业还有哪些机会?

文章目录 OpenAI发完GTP-4o,国内大模型行业还有哪些机会?详细了解一下OpenAI最新发布的支持实时语音对话的模型GPT-4o国内大模型如何寻找发展机会?想要发展技术必须要创新与追赶或许应用场景拓展也是一种出路产业生态构建 ChatGPT 问世才 17 …

网络安全之重发布与路由策略详解

重发布;import (路由导入) 将不同方式(直连、静态、缺省、其他协议)的路由器重发布进入RIP,OSPF中。 注意:1、华为中不能将缺省路由重发布进入RUO协议(思科也是一样)。…

DrugBank数据库的功能与使用

众所周知的是DrugBank数据库有两个主要辅助角色: ①临床导向的药品知识。DrugBank提供关于药品靶点和药物作用的生物或生理结果的详细、最新、定量分析或分子量的信息。 ②化学导向的药品数据库。提供计算机检索药物、药物“复原”、计算机检索药物结构数据、药物…

二叉树——堆的实现

一.前言 前面我们讲解了二叉树的概念以及二叉树的存储结构:https://blog.csdn.net/yiqingaa/article/details/139224974?spm1001.2014.3001.5502 今天我们主要讲讲二叉树的存储结构,以及堆的实现。 二.正文 1.二叉树的顺序结构及实现 1.1二叉树的顺序…

9. C++通过epoll+fork的方式实现高性能网络服务器

epollfork 实现高性能网络服务器 一般在服务器上,CPU是多核的,上述epoll实现方式只使用了其中的一个核,造成了资源的大量浪费。因此我们可以将epoll和fork结合来实现更高性能的网络服务器。 创建子进程函数–fork( ) 要了解线程我们先来了解…

聊天软件鼻祖 ICQ 将于 6 月 26 日关闭;40 光年外发现一颗潜在宜居的类地行星丨 RTE 开发者日报 Vol.212

开发者朋友们大家好: 这里是 「RTE 开发者日报」 ,每天和大家一起看新闻、聊八卦。我们的社区编辑团队会整理分享 RTE(Real-Time Engagement) 领域内「有话题的新闻」、「有态度的观点」、「有意思的数据」、「有思考的文章」、「…

就业班 第三阶段(ELK) 2401--5.22 day3 filebeat+elk云部署

kafka集群 Windterm同步输入,多台机子可以同时输入同步输入 启动kafka需要启动两个 第一个 [rootkafka1 ~]# cd /usr/local/kafka_2.11-2.0.0/ [rootkafka1 ~]# nohup bin/zookeeper-server-start.sh config/zookeeper.properties &第二个 [rootkafka1 ~]#…

关于0成本部署个人博客

分享一个文章关于零成本搭建个人博客 参考:‘关于部署博客hexoshokagithub的流程以及问题’ - 关于博客部署 | XiaoYang Guo Welcome to Guo Xiaoyangs personal blog 欢迎来到郭晓阳的个人博客 (1330303.github.io) 这个博主讲的流程很全,而且回答也…

Spark项目实训(一)

目录 实验任务一:计算级数 idea步骤分步: 完整代码: linux步骤分布: 实验任务二:统计学生成绩 idea步骤分布: 完整代码: linux步骤分步: 实验任务一:计算级数 请…

消费者相关高效读写ZK作用

消费者分区分配策略 目录概述需求: 设计思路1.消费者分区分配策略2. 消费者offset的存储3. kafka消费者组案例4. kafka高效读写&Zk作用5. Ranger分区再分析 实现思路分析 参考资料和推荐阅读 Survive by day and develop by night. talk for import biz , show …

[Java EE] 网络编程与通信原理(三):网络编程Socket套接字(TCP协议)

🌸个人主页:https://blog.csdn.net/2301_80050796?spm1000.2115.3001.5343 🏵️热门专栏:🍕 Collection与数据结构 (92平均质量分)https://blog.csdn.net/2301_80050796/category_12621348.html?spm1001.2014.3001.5482 🧀Java …

Spring MVC+mybatis项目入门:旅游网(四)用户注册——mybatis的配置与使用以及Spring MVC重定向

个人博客:Spring MVCmybatis项目入门:旅游网(四)用户注册2-持久化 | iwtss blog 先看这个! 这是18年的文章,回收站里恢复的,现阶段看基本是没有参考意义的,技术老旧脱离时代(2024年…

网络协议——FTP(简介、搭建FTP服务端)

一、简介 1、什么是FTP? FTP(File Transfer Protocol,文件传输协议) TCP/IP 协议组的协议之一。常用20(数据)、21(命令)端口作为通讯端口。(22为SSH端口)F…

BookStack VS HelpLook两款知识库软件的区别

现在很多企业都会进行知识管理,在这个过程中,选择一个合适的知识库软件是一个不可避免的问题。在众多知识库软件中,HelpLook和BookStack这两款软件备受企业瞩目。不知如何选择,今天LookLook同学就简单介绍一下这两款知识库的区别&…