In Matlab, after creating a certain number of lines and printing them to a file, I have the need to delete a line and rewrite the rest of the data to that same file. When I do so, the new data overwrites the previous data, but since the data is shorter than the original, there are still remnants of the original data. Does anyone have any idea what the best/most efficient way to delete that extra data is?
Here is a simplified example of what I'm trying to do:
fid = fopen('file.txt','w');
for i=1:10
fprintf(fid,'%i\r\t',i);
end
frewind(fid);
for i=3:5
fprintf(fid,'%i\r\t',i);
end
fprintf(fid,'EOF');
fclose(fid);
I've looked all over, but I can't seem to find the solution to my question. Any suggestions?
Without using any temp files, you can do the following:
fid = fopen('file.txt', 'wt');
for i=1:10
fprintf(fid, '%i\n', i);
end
frewind(fid);
for i=3:5
fprintf(fid, '%i\n', i);
end
pos = ftell(fid); % get current position in file
fclose(fid);
% read from begining to pos
fid = fopen('file.txt', 'r');
data = fread(fid, pos);
fclose(fid);
% overwite file with data read
fid = fopen('file.txt', 'w');
fwrite(fid, data);
fclose(fid);
Printing "EOF" won't work - nice try!
There are Unix system calls truncate and ftruncate that will do that, given either a file descriptor (truncate) or handle (ftruncate) in the first argument and a desired length in the second.
I'd try and see if Matlab supports ftruncate. Failing that... if worst came to worst you could copy-write the file to a new file, stopping and closing the new file when you hit what you consider the end of data.
To follow up on Carl Smotricz's suggestion of using two files, you can use MATLAB's DELETE and MOVEFILE commands to avoid system calls:
fid = fopen('file.txt','wt');
for i=1:10
fprintf(fid,'\t%i\r',i);
end
fclose(fid);
fid = fopen('file.txt','rt');
fidNew = fopen('fileNew.txt', 'wt');
for i = 1:2
s = fgetl(fid);
fprintf(fidNew, '%s\r', s);
end
for i=4:10
fprintf(fidNew, '\t%i\r', i);
end
fclose(fid);
fclose(fidNew);
delete('file.txt');
movefile('fileNew.txt', 'file.txt')
Related
I have a .dat file with a table containing data in following order:
0,000E+0 4,069E-2 -5,954E+0 1,851E-2
What I need to do is to read this data with matlab and then somehow handle it.
Here is my code:
path = 'C:/Users/user/Desktop/file1.dat';
fileID = fopen(path,'r');
formatSpec = '%e';
A = fscanf(fileID,formatSpec);
fclose(fileID);
disp(A);
Unfortunately, it doesn't work. What did I do wrong?
After replacement of comma with dot in data you can read it using dlmread function:
M = dlmread('filename', ' ');
M is what you want.
For the first part, replacing a character, you can use the following code:
% read the file
fid = fopen('input.txt','r');
f=fread(fid,'*char')';
fclose(fid);
%replace the char
f = strrep(f,',','.');
% write into the another file
fid = fopen('output.txt','w');
fprintf(fid,'%s',f);
fclose(fid);
function [input]= read_input()
fid= fopen ('input.txt');
tline=fgets(fid);
while ischar(tline)
if tline =='#'
end
tline = fgets(fid);
end
fclose(fid)
This is my code so far I'm trying to read a file and then just take the numerically values while skipping the lines that start with a #.
Thanks for any help in advance.
I recommend a different approach.
Take advantage of the built-in functionality MATLAB provides, and use textscan:
fid = fopen('input.txt');
C = textscan(fid, '%s', 'Delimiter', '\n', 'CommentStyle', '#');
C = C{:};
fclose(fid);
After this, you'll end up with a cell array C that contains all the lines from your input file that don't start with a hash sign.
Update the if
if tline(1) =='#'
continue;
end
I am doing an operation to get a matrix M_T. This matrix is to be saved into a text file. And this text file is to be again utilized as the primary data file. This has to be repeated for 100 times. Also in the end I want to save all the data in the 100 text files generated into a single text file named final_result.txt. I am not able to figure out how to save the different text files in different names within the loop. I tried by writing the following code. But it is showing errors.
for k=1:100
fid = fopen('data1.txt');
A = textscan(fid, '%f %f %f ') ;
%read the file
a = A{1};
b = A{2};
c = A{3};
p=[a b c];
p_t=p.';
M=rotationMatrix*p_t;
M_T=M.';
fid = fopen('data1.txt', 'wt');
fprintf(fid,' %f\t %f\t %f\n',M_T);
fclose(fid);
textfilename = ['result' num2str(k) '.txt'];
fid1 = fopen('result'k '.txt', 'wt');
fprintf(fid1,' %f\t %f\t %f\n',M_T);
fclose(fid1);
end
Try this
textfilename = ['result' num2str(k) '.txt'];
fid1 = fopen(textfilename, Write);
...
this should generate a separate file resultk.txt where k = 1,...,100.
Also, you are opening the input file twice but only closing it once. I think it would be better to close the file when you open it for reading before again opening it for writing.
If this doesn't solve the problem, try posting the specific error messages you get.
To output all files to a master file, do this before the loop starts
fidresult = fopen('final_result.txt', Write);
then at each iteration
fprintf(fidresult,' %f\t %f\t %f\n',M_T);
then after the loop is finished
fclose(fidresult)
This should output your matrix at each iteration to the master result file in addition to creating an individual file for each loop iteration
I want to read in a text file that contains some strings but mostly numbers. I want to be able to ignore the strings and only look at the numbers. I want to plot those values on a 3D plane. The data looks like this:
Tech4:<152.266724,173.189377,27.995975>
<117.880638,156.116531,27.999983>
<129.849899,59.195660,27.999983>
<249.321121,60.605404,27.999983>
<224.120361,139.072739,28.000668>
<171.188950,143.490921,56.933430>
<171.188950,143.490921,83.548088>
<171.188950,143.490921,27.999985>
I believe to read in a file is just:
File = textread('testFile.txt');
How can I only look at those values and then plot it.
Thanks!
fid = fopen([pathname,filename]);
tline = fgetl(fid);
CX = [];
CY = [];
CZ = [];
while ischar(tline)
% skip < and >
tline = substr(tline, 1, length(tline)-2)
% extract numbers
temp = textscan(tline,'%n%n%n', 'delimiter',',');
CX(end+1,:) = [temp(1)];
CY(end+1,:) = [temp(2)];
CZ(end+1,:) = [temp(3)];
tline = fgetl(fid);
end
fclose(fid);
and then plot it using
plot3(CX, CY, CZ)
function call.
Add the check for "Tech4:" at the beginning however...
I think you can also directly use textscan in a one-liner:
fid = fopen('testFile.txt');
data = textscan(fid,'%*s%f,%f,%f');
fclose(fid);
this loads the values from all rows with the specified format into the variable data.
no matlab around to test it out though.
fscanf is an option to, the same kind of parameters as textscan.
EDIT: typo, you want to detect floats (%f) of course, and not integers (%d)
EDIT2: got matlab and tested it out, this works here for your sample input ^^
fid = fopen('testFile.txt');
data = textscan(fid,'%*s%f%f%f','Delimiter',',<>')
fclose(fid);
I have a flat file saved in binary format, i want to seek to specific byte and read untile the end of that file, so we need a condition for that, what is the condition that indicates the end of the file?
By the way, i don't want to load the whole file just open the file and seek to the position i need then read until to the end of the file...
MATLAB's fread function (and, indeed, the other file IO functions) will automatically detect the end of a binary file; there's no need for a special end-of-file marker.
fread documentation
General MATLAB IO documentation
You can use feof to test for the end of a file. For example, to read a file one character at a time:
fid = fopen('bench.dat');
k = 0;
while ~feof(fid)
curr = fscanf(fid,'%c',1);
if ~isempty(curr)
k = k+1;
benchstr(k) = curr;
end
end
fclose(fid);
You can pass Inf for the size argument when using the FREAD function (will read until end of file). Here is an example:
%# first lets create a simple binary file
fid = fopen('file.bin', 'wb');
fwrite(fid, 'hello world', 'char*1');
fclose(fid);
%# now open binary file, seek to some position, and read bytes till EOF
fid = fopen('file.bin', 'rb');
fseek(fid, 6, 'bof'); %# go to the 7th byte
B = fread(fid, Inf, 'uint8=>char'); %# read bytes until end-of-file (as chars)
fclose(fid);
disp(B)