Как читать файлы с возможными заголовками в MATLAB?
Изначально у меня файлы выглядят так:
1.4 2.0
4.2 2.1
5.1 1.2
Номер столбца является фиксированным, а номера строк меняются от файла к файлу. Следующий код может читать эти файлы:
fid = fopen("my_file.txt","r");
M = fscanf(fid,"%f",[2,inf]);
Вот M
это транспонирование файла данных.
Теперь я получаю несколько новых файлов с потенциально одним заголовком строки, начинающимся с #
:
# file description
1.0 2.0
1.5 2.2
Гарантируется, что тогда header занимает не более одной строки и всегда начинается с #
,
Я знаю, что могу построчно читать файлы, чтобы иметь дело с заголовками. Интересно, можно ли как-нибудь изменить мой оригинальный код так, чтобы новый код мог читать файлы в обоих форматах.
textscanf
Кажется, что функция может заботиться о заголовках, но аргумент для поля Headerlines
является фиксированным числом.
1 ответ
Если известно, что ваши заголовки имеют префикс определенного символа, вы можете использовать textscan
"s 'CommentStyle'
NV-пара, чтобы их игнорировать:
Со следующим test.txt
:
# A header line
1 2
3 4
5 6
Мы можем использовать:
fID = fopen("test.txt", "r");
M = textscan(fID, "%f", "CommentStyle", "#");
M = reshape(M{:}, 2, []).';
fclose(fID)
Что дает нам:
>> M
M =
1 2
3 4
5 6
В качестве альтернативы, если вы хотите придерживаться fscanf
вы можете проверить первую строку файла с fgetl
и использовать frewind
при необходимости (потому что fgetl
перемещает указатель файла), чтобы вернуться к началу файла, если заголовок отсутствует.
Например:
fID = fopen("test.txt", "r");
% Test for header
tline = fgetl(fID); % Moves file pointer to next line
commentchar = "#";
if strcmp(tline(1), commentchar)
% Header present, read from line 2
M = fscanf(fID, "%f", [2, inf]).';
else
% Header present, rewind to beginning of file & read as before
frewind(fID);
M = fscanf(fID, "%f", [2, inf]).';
end
fclose(fID);
Что дает тот же результат, что и выше. Если количество строк заголовка не является постоянным, вы можете использовать ftell
а также fseek
с while
цикл, чтобы пропустить прошлые заголовки, но в этот момент вы, вероятно, делаете вещи более сложными, чем они действительно должны быть для этого приложения.