如何在MATLAB中读取带有可能标题的文件?

时间:2018-04-11 14:50:58

标签: matlab file-io formatted-input

最初我的文件看起来像:

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

保证标题占用不超过一行,并始终以#开头。

我知道我可以逐行读取文件来处理标题。我想知道是否有任何方法可以对原始代码进行尽可能少的更改,以便新代码可以读取两种格式的文件。

textscanf函数似乎能够处理标题,但字段Headerlines的参数是固定数字。

1 个答案:

答案 0 :(得分:3)

如果已知您的标题带有特定字符的前缀,那么您可以使用textscan'CommentStyle' NV-pair忽略它们:

使用以下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);

其结果与上述相同。如果标题行的数量不是常数,您可以使用ftellfseek并使用while循环来跳过标题,但此时您可能正在制作内容比这个应用程序真正需要的更复杂。