文本大小和文件中位置之间的关系



让我们假设我们有以下文本'badpoeem.txt',其中包含以下句子

Oranges and lemons,
Pineapples and tea.
Orangutans and monkeys,
Dragonflys or fleas.

i确定字节中每个句子的大小

 whos
  Name        Size            Bytes  Class     Attributes
  ans         1x1                 8  double              
  fid         1x1                 8  double              
  tline1      1x19               38  char                
  tline2      1x19               38  char                
  tline3      1x23               46  char   

其中tline1,tline2和tline3是相应的文本,现在我打开文件并读取三次文本时,我已经检查了当前的文件位置,这是第一个

的结果
fid = fopen('badpoem.txt');
ftell(fid)
ans = 0

它正在打开,所以很好,现在阅读第一个文本

tline1 = fgetl(fid)  % read the first line
ftell(fid)
tline1 =
    'Oranges and lemons,'

ans =
    21
 now lets read second file
tline2 = fgetl(fid)
ftell(fid)
tline2 =
    'Pineapples and tea.'

ans =
    42            

最后一个

tline3 = fgetl(fid)
ftell(fid)
tline3 =
    'Orangutans and monkeys,'

ans =
    67

文本和位置的大小之间是否有任何关系?预先感谢

用于文本文件Windows在每行末尾添加两个字符,其他系统添加一个字符。MATLAB,当阅读一行时,在返回的字符串中跳过这些线,但是由于Windows添加了两个,而不是一个,您获得Windows的位置值与MATLAB示例中所示的不同位置值:

https://www.mathworks.com/help/matlab/ref/ref/ftell.html

char字符串使用一个字节保存在文件中,但将每个字符存储在MATLAB的内存中,为16位单词或2个字节,每个字符都使char字符串的明显大小加倍。

确实很好的问题。实际上,我认为是什么让您感到困惑的是,您正在处理许多不同的问题混合在一起。让我们一个一个一个。


1(Windows下的TXT文件格式

通常(亚洲语言环境和高级文本编辑器是常见的例外(,Windows下的文本文件是ANSI编码的(其中ANSI是参考ISO/IEC 8859编码的通用方法(。在此编码框架中,从二进制角度来看,每个字符由单个字节表示。如果您用Notepad打开此类TXT文件并粘贴了一些中文意识形态,这是您尝试保存更改时会看到的消息:

此文件包含单码格式的字符,如果 您可以将此文件保存为ANSI编码的文本文件。保持Unicode 信息,单击下面的取消,然后选择一个Unicode之一 从编码下拉列表中的选项。继续?

2(Windows下的线分隔符

正如其他用户已经指出的那样,在Windows中,默认线路断裂由两个字符的组合表示:托架返回(更称为r0xD(和线供稿(更称为n0xA(。这是基于您的文本的示例:

Oranges and lemons,rnPineapples and tea.rnOrangutans and monkeys,rnDragonflys or fleas.

诸如Linux和MacOS之类的其他操作系统不会发生这种情况,其中仅支持线馈:

Oranges and lemons,nPineapples and tea.nOrangutans and monkeys,nDragonflys or fleas.

3(在MATLAB下的字符串存储

matlab将字符存储在内存中,为Unicode 16位无符号整数,每个整数占每个字节。这不取决于当前的MATLAB编码(可以检索执行命令feature('DefaultCharacterSet'),默认情况下,对应于当前的操作系统编码(。

4(fgetl函数

根据官方文档,fgetl函数从文件(指定性,有效的文件句柄(中读取单个行不包括线路断路。这意味着MATLAB读取了整个行,包括所有断路字符,但是它们是从函数返回的输出字符串中修剪出来的。

fgetlfgets之间的区别在于前者修剪线路断裂,而后者则没有。


这都是这样说的,让我们逐步分析您的代码中正在发生的事情。首先,您打开文件,并且指针放在流的开头:

fid = fopen('data.txt','r');
ftell(fid) % 0

然后,您阅读第一行:

tline1 = fgetl(fid)
ftell(fid) % 21

该行包含19字符(您从whos表中获得的大小(,由于Unicode而使用38字节存储,该字符是存储端的。ftell调用显示数字21,因为fgetl读取了整个行,其中包含两个已从输出中修剪的线断裂字符(0 + 19 + 2 = 21(。

然后,您阅读第二行:

tline2 = fgetl(fid)
ftell(fid) % 42

该行包含使用38字节存储内存侧的19字符。ftell调用显示数字42,因为fgetl读取整个行,其中包含两个已从输出中修剪的线断裂字符。从上一个偏移量,21 + 19 + 2 = 42

最后,您阅读了第三行:

tline3 = fgetl(fid)
ftell(fid) % 67

该行包含使用46字节存储内存侧的23字符。ftell调用显示数字67,因为fgetl读取整个行,其中包含两个已从输出中修剪的线断裂字符。从上一个偏移量,42 + 23 + 2 = 67

最新更新