How can I scan a text file in order to read a specific number in a line?

25 views (last 30 days)
wese112
wese112 on 30 Mar 2016
Commented: dpb on 30 Mar 2016
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.

Answers (2)

dpb
dpb on 30 Mar 2016
Edited: dpb on 30 Mar 2016
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 Comments
dpb
dpb on 30 Mar 2016
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.

Sign in to comment.


MHN
MHN on 30 Mar 2016
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 Comments
dpb
dpb on 30 Mar 2016
"_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).

Sign in to comment.

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!