fscanf函数的奇怪行为

mag*_*gva 4 matlab scanf

我试图用Matlab的fscanf函数读取一个小配置文件中包含的信息.文件的内容是;

YAcex: 1.000000
YOx: 1.000000
KAce: 1.000000
Run Code Online (Sandbox Code Playgroud)

用于解析文件的matlab代码是;

fh = fopen('parameters', 'r');
fscanf(fh, 'YAcex: %f\n')
fscanf(fh, 'YOx: %f\n')
fscanf(fh, 'KAce: %f\n')
fclose(fh);
Run Code Online (Sandbox Code Playgroud)

调用此脚本时,只能正确读取"YAcex"行; fscanf返回[]另外两行.如果切换YOx和KAce线(在YOx之前KAce),fscanf将正确读取所有线.

有人可以解释这种行为吗?

补充信息:输入文件中的换行符是简单的换行符(\n字符,没有\ r \n字符).

gno*_*ice 8

您的问题是您只想在每次调用时读取一个值fscanf,但默认情况下它会尝试读取尽可能多的值.请注意文档中的摘录:

fscanf函数在整个文件中重新应用格式,并将文件指针定位在文件结束标记处.如果fscanf无法匹配formatSpec数据,则只读取匹配的部分并停止处理.

这意味着第一次调用正确读取文件的第一行,但随后也尝试读取下一行,找不到与其格式说明符的完全匹配.它找到下一行的部分匹配,其中第一行匹配格式说明符的开头.这部分匹配直接放置文件指针的中,导致下次调用失败,因为它是在开始的.我们可以用以下方式说明:YYOx:YAcex:YYOx:fscanfOx: ...ftell

fh = fopen('parameters', 'r');
fscanf(fh, 'YAcex: %f\n');
ftell(fh)

ans =

    18    % The "O" is the 18th character in the file
Run Code Online (Sandbox Code Playgroud)

切换YOx:KAce:行时,下一行的部分匹配不再发生,因此文件指针每次都在下一行的开头结束,并且所有读取都成功.

那么,你怎么能解决这个问题呢?一种选择是始终指定size参数,因此fscanf不会不必要地重新应用格式说明符:

fh = fopen('parameters', 'r');
fscanf(fh, 'YAcex: %f\n', 1);
fscanf(fh, 'YOx: %f\n', 1);
fscanf(fh, 'KAce: %f\n', 1);
fclose(fh);
Run Code Online (Sandbox Code Playgroud)

另一种选择是在一行中完成所有这些:

fh = fopen('parameters', 'r');
values = fscanf(fh, 'YAcex: %f\n YOx: %f\n KAce: %f\n');
fclose(fh);
Run Code Online (Sandbox Code Playgroud)

并且values将是一个3×1的数组,包含文件中的3个值.