Как читать файлы с возможными заголовками в 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 цикл, чтобы пропустить прошлые заголовки, но в этот момент вы, вероятно, делаете вещи более сложными, чем они действительно должны быть для этого приложения.

Другие вопросы по тегам