How can I scan a text file in order to read a specific number in a line?
조회 수: 2 (최근 30일)
이전 댓글 표시
Hello, I am having trouble getting matlab to scan a text file and read back data to me from that txt file. For example the txt file contains this:
So I want matlab to ask me to input a number and when I input that number between 0 to 5 it will give me back the resultant Po/P valve of that number or if it doesn't exist it will create an error.
I would really appreciate any help.
댓글 수: 0
답변 (2개)
dpb
2016년 3월 30일
편집: dpb
2016년 3월 30일
Don't try to read from a file each time; read the data into memory and use lookup...
>> M=0:0.5:5;
>> P=[1,.8,.5,.3,.1,.06,.03,.03,.006,.003,.002]; % approximate values for ease
>> V=2;
>> if(isempty(find(M==V))),error('Value not in set'),else disp(P(M==V)),end
0.1000
>> V=1.25;
>> if(isempty(find(M==V))),error('Value not in set'),else disp(P(M==V)),end
Value not in set
>>
Put into a utility function if used multiple places or to return result, of course.
ADDENDUM
OK, for the input question...
First with fprintf
fid=fopen('test.txt');
fgetl(fid); % skip the header line
A=fscanf(fid,'%f %f',[2,inf]).'; % NB count and transpose to get order
fid=fclose(fid);
With dlmread
>> A=dlmread('test.txt',[],1,0); % default delimiter, skip header row
With textread
>> [M P]=textread('test.txt','%f%f','headerlines',1); % two variables automagically
While given "red-haired stepchild" status by TMW, textread has much to say for it in not having to use fopen/fclose pair and that it returns double instead of only cell arrays for simple cases such as this.
If were to use textscan, for this case I'd use it as
A=cell2mat(textscan(fid,'','headerlines',1,'collectoutput',1));
to return a double array instead of cell directly and the empty format string as it will return the right-sized array w/o counting the number of fields/record which is a help particularly if don't know that a priori. Of course, you have to have opened the file and subsequently close it.
ADDENDUM 2
Re: question of file vis a vis memory--as noted there's apparently so little data here that it's inconsequential but it'll be far more efficient to have all the data in memory as noted before; the amount of which will only increase if the lookup occurs multiple times.
If this process occurs once, say, at the beginning of a piece of code, then you kinda' "have your cake and eat it, too!" if you place this in a function as the data will go away when the function returns and you don't have it cluttering up things when done.
OTOH, if this occurs over and over throughout the lifetime of the application you're building, then it makes sense to read the file first and pass the data; rereading a file over and over sequentially searching for a value is extremely inefficient and to be avoided it at all possible. Also as noted earlier, if the file were to be huge, having a database where could do a query would be a possible solution; Matlab doesn't support that out-of-the-box but there are other ways to structure the file so that you wouldn't have to do a sequential read of a zillion records to find one, but still with today's memory it's generally not an issue to just hold what data one needs in memory and go until it is shown to not be a viable alternative.
댓글 수: 2
dpb
2016년 3월 30일
편집: dpb
2016년 3월 30일
Why fscanf, specifically? As noted earlier below, I simply showed above one manner in which to do the lookup; you can't do anything with data in the file until you read it in; while it would be possible to parse the file over and over, there's absolutely no reason to do it that way unless it were to be megabytes in size and in that event you'd want some other way than just a sequential file to have the data.
Returning to the specific question asked, fscanf is a low-level i/o function; there are a zillion others for reading text files such as you have with a header line which fscanf doesn't have the facility to handle. Use the toolset provided in Matlab; don't try to write C.
In practice, I'd probably use dlmread for a simple file such as you have which will give you an array instead of cell array, or textread which can give you the two variables directly which has some merit in named variables w/o array indexing as in my selection coding.
MHN
2016년 3월 30일
See the attachment for test.txt and put it in the current directory.
fileID = fopen('test.txt');
A = textscan(fileID,'%f %f','Delimiter',' ','MultipleDelimsAsOne',1);
M1 = A{1,1};
M2 = A{1,2};
x = input('value for M ?')
ind = M1==x;
if sum(ind)==0
display('Error')
else
M2(ind)
end
fclose(fileID);
댓글 수: 4
dpb
2016년 3월 30일
편집: dpb
2016년 3월 30일
Sure, but what difference does it make? The above reads the file into a cell array instead of an "ordinary" double array I assumed above then does the lookup in a slightly different fashion.
You can only read them into memory to do anything with the data so instead of wasting overhead time and time again reading and parsing, do it once up front and then use the result from memory. In these days of humongous memory footprints, a few extra data points is nothing.
dpb
2016년 3월 30일
"_But can you do the same using the fscanf function?"_
I'm wondering if you're reading more into the name fscanf than there is...it does NOT search for text or a value in the file, it simply converts the data from external to internal form depending upon the specific format string given (which has to match what's in the file, hopefully, obviously).
There are disk utilities that will do such a thing, but again it's the high-overhead way to approach the problem. Search the web for "grep" for the classic --nix utility; there are versions for any OS (but it still isn't the best solution to your question in Matlab).
참고 항목
카테고리
Help Center 및 File Exchange에서 Text Files에 대해 자세히 알아보기
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!