Очень хороший вопрос, действительно. На самом деле, я думаю, что вас смущает тот факт, что вы сталкиваетесь с множеством разных проблем, смешанных вместе. Давайте проанализируем их один за другим.
1) Формат файла TXT в Windows
Обычно (азиатские локали и расширенные текстовые редакторы являются распространенным исключением), текстовые файлы под Windows кодируются ANSI
(где ANSI
- это общий способ ссылки на кодировки ISO/IEC 8859
). В этой структуре кодирования с двоичной точки зрения каждый символ представлен одним байтом. Если вы откроете такие TXT
файлы с помощью Notepad
и вставите в них несколько китайских идеограмм, это сообщение вы увидите при попытке сохранить изменения:
Этот файл содержит символы в формате Unicode, которые будут потеряны, если
Вы сохраняете этот файл как текстовый файл в кодировке ANSI. Сохранить юникод
информация, нажмите Отмена ниже, а затем выберите один из Unicode
вариант из раскрывающегося списка Кодировка. Продолжить?
2) Разделители строк под Windows
Как уже отмечали другие пользователи, в Windows разрыв строки по умолчанию представлен комбинацией двух символов: возврат каретки (более известный как \r
или 0xD
) и перевод строки (более известный как \n
или 0xA
). Вот пример на основе вашего текста:
Oranges and lemons,\r\nPineapples and tea.\r\nOrangutans and monkeys,\r\nDragonflys 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 читает всю строку, включая все символы разрыва строки, но они обрезаются из выходной строки, возвращаемой функцией.
Разница между fgetl
и fgets
заключается в том, что первый обрезает разрыв строки, а второй - нет.
Все это, как говорится, давайте шаг за шагом проанализируем, что происходит в вашем коде. Сначала вы открываете файл, и указатель помещается в начало потока:
fid = fopen('data.txt','r');
ftell(fid) % 0
Затем вы читаете первую строку:
tline1 = fgetl(fid)
ftell(fid) % 21
Строка содержит 19
символов (размер, который вы получаете из таблицы whos
), которые на стороне памяти хранятся с использованием 38
байтов из-за Unicode. Вызов ftell
отображает число 21
, потому что fgetl
читает всю строку, которая включает два символа разрыва строки, которые были обрезаны из вывода (0 + 19 + 2 = 21
).
Затем вы читаете вторую строку:
tline2 = fgetl(fid)
ftell(fid) % 42
Строка содержит 19
символов, которые на стороне памяти сохраняются с использованием 38
байтов. Вызов ftell
отображает число 42
, потому что fgetl
читает всю строку, которая включает в себя два символа разрыва строки, которые были обрезаны на выходе. Из предыдущего смещения 21 + 19 + 2 = 42
.
Наконец, вы читаете третью строку:
tline3 = fgetl(fid)
ftell(fid) % 67
Строка содержит 23
символов, которые на стороне памяти хранятся с использованием 46
байтов. Вызов ftell
отображает число 67
, потому что fgetl
читает всю строку, которая включает в себя два символа разрыва строки, которые были обрезаны на выходе. Из предыдущего смещения 42 + 23 + 2 = 67
.