小丑9 发表于 2022-3-4 18:44:38

同样的代码,读取不同的文件的时候会报错

本帖最后由 小丑9 于 2022-3-4 18:46 编辑


#编写一个程序,当用户输入文件名和行数(N)后,将该文件的前N行内容打印到屏幕上。
#用户可以随意输入需要显示的行数。(如输入13:21打印第13行到第21行,输入:21打印前21行,输入21:则打印从第21行开始到文件结尾所有内容)
#这是问题


def file_view(file_name, line_num):
    if line_num.strip() == ':':
      begin = '1'
      end = '-1'

    (begin, end) = line_num.split(':')

    if begin == '':
      begin = '1'
    if end== '':
      end = '-1'

    if begin == '1' and end == '-1':
      prompt = '的全文'
    elif begin == '1':
      prompt = '从开始到%s' % end
    elif end == '-1':
      prompt = '从%s到结束' % begin
    else:
      prompt = '从第%s行到第%s行' % (begin, end)

    print('\n文件%s%s的内容如下:\n' % (file_name, prompt))

    begin = int(begin) - 1
    end = int(end)
    lines = end - begin

    f = open(file_name)

    for i in range(begin):# 用于消耗掉begin之前的内容
      f.readline()

    if lines < 0:
      print(f.read())
    else:
        for j in range(lines):
            print(f.readline(), end='')

    f.close()


file_name = input(r'请输入要打开的文件(C:\\test.txt):')
line_num = input('请输入需要显示的行数【格式如 13:21 或 :21 或 21: 或 : 】:')
file_view(file_name, line_num)


同样的代码,当读取的文件是数字时,不会报错,但如果是文字的话就会报错,显示下面 这个,这是为什么?

D:\Python\python.exe D:/系统/练习/作业.py
请输入要打开的文件(C:\\test.txt):国歌.txt
请输入需要显示的行数【格式如 13:21 或 :21 或 21: 或 : 】::

文件国歌.txt的全文的内容如下:

Traceback (most recent call last):
File "D:\系统\练习\作业.py", line 44, in <module>
    file_view(file_name, line_num)
File "D:\系统\练习\作业.py", line 34, in file_view
    print(f.read())
UnicodeDecodeError: 'gbk' codec can't decode byte 0x81 in position 8: illegal multibyte sequence

进程已结束,退出代码1



ba21 发表于 2022-3-4 19:01:34

本帖最后由 ba21 于 2022-3-4 20:11 编辑

000111

ckblt 发表于 2022-3-4 19:02:06

可能是编码问题,
f = open(file_name)
改成f = open(file_name, encoding="utf-8")
试试

小丑9 发表于 2022-3-4 19:27:13

ba21 发表于 2022-3-4 19:01
文件保存是有编码的,同样你读取也要使用相应的编码读取。
使用cchardet判断字符编码(准确度高)
cchard ...

我没学编码啥的,看不懂啊,可不可以通俗易懂点{:10_266:}

xiaosi4081 发表于 2022-3-4 19:38:18

小丑9 发表于 2022-3-4 19:27
我没学编码啥的,看不懂啊,可不可以通俗易懂点

编码可以理解为打开文件用什么语言

比如说用我们普通话去听英文,这肯定不行

又比如说用英文去听中文,也不行

python常用的编码有utf-8和gbk

utf-8一般不会出现乱码

所以把打开文件的那行改成:

f = open(file_name, encoding="utf-8")

isdkz 发表于 2022-3-4 19:48:23

本帖最后由 isdkz 于 2022-3-4 19:49 编辑

小丑9 发表于 2022-3-4 19:27
我没学编码啥的,看不懂啊,可不可以通俗易懂点

因为计算机只会跟 二进制 打交道,所以字符存到计算机里都是用特定的二进制序列来保存的,

而 二进制序列 到 字符 的对应关系就是编码,像一些普通的字符,在计算机发展初期就存在了的,

比如数字,字母等等 ascii 编码的字符,ascii 编码是最早的编码,它只需要一个字节,

不过一个字节只有 8 个 二进制位,还有 1 位用作保留位,也就是只剩下 7 位可用,

所以 ascii 只能表示 2 的 7 次方也就是 128 个字符,

这很显然对于这个世界的字符数量来说是远远不够的,

所以发展到后来的 unicode,utf-8,gbk 等编码。

计算机处理数据是以 字节 为单位的(因为早期的计算机就是 8 位的,一直发展到现在的 64 位),

所以 ascii 字符无论如何也不会乱码,也不会出现编码错误,

这就是你读取的文件都是数字时不会出现错误的原因,

而中文字符至少需要 2 个字节(gbk 编码使用 2 个字节表示中文字符,

utf-8 编码使用 3 个字节表示中文字符),

所以你就得按对应的编码格式打开文件才能正常解码,

从你的报错信息可知,gbk 无法解码你的文件,

那你就得打开文件的时候指定 utf-8 编码打开。

故对你的代码修改如下:

#编写一个程序,当用户输入文件名和行数(N)后,将该文件的前N行内容打印到屏幕上。
#用户可以随意输入需要显示的行数。(如输入13:21打印第13行到第21行,输入:21打印前21行,输入21:则打印从第21行开始到文件结尾所有内容)
#这是问题


def file_view(file_name, line_num):
    if line_num.strip() == ':':
      begin = '1'
      end = '-1'

    (begin, end) = line_num.split(':')

    if begin == '':
      begin = '1'
    if end== '':
      end = '-1'

    if begin == '1' and end == '-1':
      prompt = '的全文'
    elif begin == '1':
      prompt = '从开始到%s' % end
    elif end == '-1':
      prompt = '从%s到结束' % begin
    else:
      prompt = '从第%s行到第%s行' % (begin, end)

    print('\n文件%s%s的内容如下:\n' % (file_name, prompt))

    begin = int(begin) - 1
    end = int(end)
    lines = end - begin

    f = open(file_name, encoding='utf-8')            # 指定编码格式为 utf-8

    for i in range(begin):# 用于消耗掉begin之前的内容
      f.readline()

    if lines < 0:
      print(f.read())
    else:
      for j in range(lines):
            print(f.readline(), end='')

    f.close()


file_name = input(r'请输入要打开的文件(C:\\test.txt):')
line_num = input('请输入需要显示的行数【格式如 13:21 或 :21 或 21: 或 : 】:')
file_view(file_name, line_num)

小丑9 发表于 2022-3-4 20:09:44

isdkz 发表于 2022-3-4 19:48
因为计算机只会跟 二进制 打交道,所以字符存到计算机里都是用特定的二进制序列来保存的,

而 二进 ...

感谢!
页: [1]
查看完整版本: 同样的代码,读取不同的文件的时候会报错