编译器无法解码
代码报错:utf-8”编解码器无法解码位置3中的字节0xd0:无效的继续字节
查找文件中关键字的具体位置代码如下:
import os
def print_pos(key_dict):
keys = key_dict.keys()
keys = sorted(keys) # 由于字典是无序的,我们这里对行数进行排序
for each_key in keys:
print('关键字出现在第 %s 行,第 %s 个位置。' % (each_key, str(key_dict)))
def pos_in_line(line, key):
pos = []
begin = line.find(key)
while begin != -1:
pos.append(begin + 1) # 用户的角度是从1开始数
begin = line.find(key, begin+1) # 从下一个位置继续查找
return pos
def search_in_file(file_name, key):
f = open(file_name,encoding='utf-8')
count = 0 # 记录行数
key_dict = dict() # 字典,用户存放key所在具体行数对应具体位置
for each_line in f:
count += 1
if key in each_line:
pos = pos_in_line(each_line, key) # key在每行对应的位置
key_dict = pos
f.close()
return key_dict
def search_files(key, detail):
all_files = os.walk(os.getcwd())
txt_files = []
for i in all_files:
for each_file in i:
if os.path.splitext(each_file) == '.txt': # 根据后缀判断是否文本文件
each_file = os.path.join(i, each_file)
txt_files.append(each_file)
for each_txt_file in txt_files:
key_dict = search_in_file(each_txt_file, key)
if key_dict:
print('================================================================')
print('在文件【%s】中找到关键字【%s】' % (each_txt_file, key))
if detail in ['YES', 'Yes', 'yes']:
print_pos(key_dict)
key = input('请将该脚本放于待查找的文件夹内,请输入关键字:')
detail = input('请问是否需要打印关键字【%s】在文件中的具体位置(YES/NO):' % key)
search_files(key, detail)
编码问题,需要把f = open(file_name,encoding='utf-8')这句的 'utf-8'改成 'gbk isdkz 发表于 2022-2-14 11:50
编码问题,需要把f = open(file_name,encoding='utf-8')这句的 'utf-8'改成 'gbk
还是报错
请将该脚本放于待查找的文件夹内,请输入关键字:'3'
请问是否需要打印关键字【'3'】在文件中的具体位置(YES/NO):yes
Traceback (most recent call last):
File "E:/编码程序/python/n2n14.py", line 56, in <module>
search_files(key, detail)
File "E:/编码程序/python/n2n14.py", line 46, in search_files
key_dict = search_in_file(each_txt_file, key)
File "E:/编码程序/python/n2n14.py", line 25, in search_in_file
for each_line in f:
UnicodeDecodeError: 'gbk' codec can't decode byte 0xab in position 74: illegal multibyte sequence
本帖最后由 isdkz 于 2022-2-14 11:58 编辑
不弃_ 发表于 2022-2-14 11:53
还是报错
请将该脚本放于待查找的文件夹内,请输入关键字:'3'
请问是否需要打印关键字【'3'】在文件中 ...
因为你的文件不一定统一编码,你可以以二进制打开,一次读取所有的内容,检测一下编码再解码
这个可以用python内置模块chardet,你可以先按我说的研究一下,我帮你调试好了再放代码上来
像这种需要遍历整个文件夹下 txt 文本的,容易出现编码不一致问题
你可能前一个文件是 utf-8 的编码,而后一个就是 Gbk 编码,又或者是其他
所以若你单纯想测试代码,可以将代码中的 txt 文件全部重新另存为 设置编码统一的编码集
若你想通用,就需要用到 chardet 模块,进行读取文件对象的编码,通过 open 的 'rb' 模式二进制读取文件对象 f
然后调用,ed = chardet.detect(f.read())['encoding'] 就可以获取此时文件的编码
再重新通过 open(file_name,encoding = ed) 设置好文件编码,打开文件
本帖最后由 isdkz 于 2022-2-14 12:24 编辑
你先看一下,我还没有测试,有问题再讨论
import os
import chardet # 加上这句
def print_pos(key_dict):
keys = key_dict.keys()
keys = sorted(keys) # 由于字典是无序的,我们这里对行数进行排序
for each_key in keys:
print('关键字出现在第 %s 行,第 %s 个位置。' % (each_key, str(key_dict)))
def pos_in_line(line, key):
pos = []
begin = line.find(key)
while begin != -1:
pos.append(begin + 1) # 用户的角度是从1开始数
begin = line.find(key, begin+1) # 从下一个位置继续查找
return pos
def search_in_file(file_name, key):
with open(file_name, 'rb') as f: # 改这里
raw = f.read() # 加上这句
if not raw: # 加上这句
return # 加上这句
text = raw.decode(chardet.detect(raw)['encoding']) # 加上这句
lines = text.splitlines()
count = 0 # 记录行数
key_dict = dict() # 字典,用户存放key所在具体行数对应具体位置
for each_line in lines: # f改成lines
count += 1
if key in each_line:
pos = pos_in_line(each_line, key) # key在每行对应的位置
key_dict = pos
# f.close() 删掉这句
return key_dict
def search_files(key, detail):
all_files = os.walk(os.getcwd())
txt_files = []
for i in all_files:
for each_file in i:
if os.path.splitext(each_file) == '.txt': # 根据后缀判断是否文本文件
each_file = os.path.join(i, each_file)
txt_files.append(each_file)
for each_txt_file in txt_files:
key_dict = search_in_file(each_txt_file, key)
if key_dict:
print('================================================================')
print('在文件【%s】中找到关键字【%s】' % (each_txt_file, key))
if detail in ['YES', 'Yes', 'yes']:
print_pos(key_dict)
key = input('请将该脚本放于待查找的文件夹内,请输入关键字:')
detail = input('请问是否需要打印关键字【%s】在文件中的具体位置(YES/NO):' % key)
search_files(key, detail)
isdkz 发表于 2022-2-14 12:09
你先看一下,我还没有测试,有问题再讨论
open()的默认编码是gbk吗?open(file, mode='r', buffering=-1, encoding=None, errors=None, newline=None, closefd=True, opener=None) 不弃_ 发表于 2022-2-14 12:11
open()的默认编码是gbk吗?open(file, mode='r', buffering=-1, encoding=None, errors=None, newline=No ...
open的默认编码是根据当前的语言环境,你可以使用locale模块查看
>>> import locale
>>> locale.getpreferredencoding()
'cp936'
>>> isdkz 发表于 2022-2-14 12:09
你先看一下,我还没有测试,有问题再讨论
报错
Traceback (most recent call last):
File "E:/编码程序/python/n2n14.py", line 2, in <module>
import chardet # 加上这句
ModuleNotFoundError: No module named 'chardet'
locale.getpreferredencoding()
不弃_ 发表于 2022-2-14 12:25
报错
Traceback (most recent call last):
File "E:/编码程序/python/n2n14.py", line 2, in
找不到就安装一下吧,我看网上说这个模块是内置的 还有个问题就是你判断输入的选项的时候大小写混用有很多种情况,你不能把每一种都枚举出来,你可以先处理一下输入
if detail in ['YES', 'Yes', 'yes']:
print_pos(key_dict)
改成
if detail.lower() == 'yes:
print_pos(key_dict) isdkz 发表于 2022-2-14 12:18
open的默认编码是根据当前的语言环境,你可以使用locale模块查看
那就是说所有文件有两个或两个以上的编码,open()就打不开报错。只要统一编码就不会报错。
是这样的吗? isdkz 发表于 2022-2-14 12:30
还有个问题就是你判断输入的选项的时候大小写混用有很多种情况,你不能把每一种都枚举出来,你可以先处理一 ...
不错
不弃_ 发表于 2022-2-14 12:31
那就是说所有文件有两个或两个以上的编码,open()就打不开报错。只要统一编码就不会报错。
是这样的吗?
对的,默认它不会帮你自动检测编码,而是根据你当前语言环境给你指定的
页:
[1]