Trying to use fopen and fprintf with matlab, only writing once - matlab

I'm having trouble writing to a file here... I must be making a simple mistake but I can't find it. Anyways, here's the code:
ages = 1;
while (ages > 0)
fileID = fopen('age.txt', 'w'); %opens file
ages = input('Enter an age (negative to quit): '); %user input
if(ages > 0) %so it doesn't add on the break number
fprintf(fileID, '%d\r\n', ages);
end
end
fclose(fileID);
My problem is that it writes nothing to the file. If I remove the if statement it writes only -1 to the file (using -1 as the negative 'quit' number).
What am I missing?

Easy,
Your fopen command is inside the loop ... so each time "it opens file for writing and discard existing contents, if any" (w mode).
Put fopen outside while loop.

Related

MATLAB : read data file in real time

I have an application, A, that writes to a File.
I want to use MATLAB to read N lines in realtime from this file.
My question is related to this stack post: How to plot real time data from text file in MATLAB
The author of one of the answers, mentions the following approach:
You can't plot using hard real time conditions, thus it can always happen that matlab misses a 10ms timeslot. You have to use option 2 to get all data.
To get started: Write a function which only reads the new data which was written since last call. To achieve this, do not close the file handle. It stores the position.
As such, here is my code:
myfile_fid=fopen(filePath, 'rt')
waitForFileToHaveData(filePath, 10);
for readingIdx = 1:10
fgetl(myfile_fid)
end
My waitForFileToHaveData function, is defined as follows:
function waitForFileToHaveData(filePath, desired_length)
if (getNumLinesOfFile(filePath) < desired_length)
disp('###### not enough data in the file');
pause(0.02);
waitForFileToHaveData(filePath, desired_length);
end
end
function num = getNumLinesOfFile(file_to_read)
[status, result] = system( ['wc -l ', file_to_read] );
if(status~=1)
scanCell = textscan(result,'%u %s');
num = scanCell{1} - 2;
else
num = 0;
end
end
Result:
When I get into the for loop, myfile_fid evaluates to 3, while fgetl(myfile_fid) evaluates to -1. If I print out the results of getNumLinesOfFile(filePath), I see 20. The odd part is that if I wait, say for the file to have 40 lines, and execute the code above, I do not get the error. I tried to look at the documentation to see why fgetl returns back -1, but I cannot seem to find it in 2018b MATLAB documentation. There is mention that the myfile_fid can return a -1, but that is only if the file cannot be opened. However, at runtime, myfile_id evaluates to 3.
Using MATLAB, is it possible to read N number of lines since last read in a file that is being written to by another application?
fgetl returns -1 when fileID reaches the end-of-file marker, See Matlab fgetl documentation. This means that if the first result from fgetl is -1 then the file is empty.
I'm not sure why you are getting -1 if getNumLinesOfFile returns 20, check the code carefully if you are reading the same file. Maybe the file has changed?
I wrote here MATLAB code that checks if 10 new lines were added and and then gets them with fgetl:
myfile_fid = fopen(filePath, 'rt');
newLines = 10;
linesRead = 0;
while(waitForFileToHaveData(filePath, linesRead + newLines))
linesRead = linesRead + newLines;
for readingIdx = 1:newLines
line = fgetl(myfile_fid)
end
end
fclose(myfile_fid);
I updated the waitForFileToHaveData function to return 1:
function ready = waitForFileToHaveData(filePath, desired_length)
while (getNumLinesOfFile(filePath) < desired_length)
disp('###### not enough data in the file');
pause(0.02);
end
ready = 1;
end
Note:
If the file had exactly 10 lines with no end-line marker at line 10, and you read them, then another 10 lines were added, fileID now points to the end-line of line 10 and the first line fgetl will return is the end-line at line 10, but since fgetl removes the end-line, it returns an empty array.
Side note:
the function waitForFileToHaveData uses recursion which is inefficient. You can easily use a while loop.

Create a separate log file for each iteration in a for loop

I just want to make a script which runs multiple files and stores their outputs in separate log files.
So I wrote the code by using diary to generate the output, but the diary function is only 1 log file and the output is updating in the same log file for remaining iterations. In my testconfig_1 file, I have at present only print as the content.
Then I tried to use the fopen method, with this I am getting multiple log files but I don't understand how I can put that data into the log file which I have created through fopen after each run.
% with diary method
clear all;
diary on;
instring ='testconfig_';
for x = 1:3
fprintf ('Simulation on testconfig_%d \n' , x);
test = [instring num2str(x)];
run(test);
diary testconfig_(x).log;
end
% without diary method
clear all;
diary on;
instring ='testconfig_';
for x = 1:3
fprintf ('Simulation on testconfig_%d \n', x);
test = [instring num2str(x)];
run(test);
fid = fopen(sprintf('testconfig_%d.log',x),'w');
end
I wanted to get testconfig_1.log, testconfig_2.log, testconfig_3.log and I wanted to print in_testconfig_1, in_testconfig_2, in_testconfig_3 respectively
You are using command syntax to call the diary function.
% Command syntax
diary filename.log
% Equivalent function syntax
diary( 'filename.log' );
Notice that, when using command syntax, all arguments are treated as strings, despite not having any quote marks!
So when you do diary testconfig_(x).log, the equivalent is
diary( 'diary testconfig_(x).log' );
All of your logs have the same filename, because x is never evaluated as the loop variable, it's always just part of a string!
You are trying to create the strings with the loop variable in the name, for this you cannot use command syntax.
Instead, use function syntax like this:
filename = sprintf( 'diary testconfig_%d.log', x );
diary( filename ); % treat the filename variable as a variable, not a string
You don't have to declare the intermediate filename variable, and there are other ways to create the filename string, but I hope this demonstrates the issue.

Problems using Matlab function eps2pdf

I have a Matlab script where I produce a figure, and then create an eps file in my current directory using the command
print('myFile','-depsc'). Immediately following, I have: mypdf = eps2pdf('myFile').
I get the error message that 'Error while creating temporary eps file: ..... cannot be accessed or does not exist'.
Has anyone had a similar problem? Any suggestions what I might be doing wrong? I'm using Ubuntu and Matlab 2017a.
Here is an example code that I type into the command line. I get the error message which I stated above.
figure()
plot(linspace(1,100),linspace(1,100)) %Simple line
print('my_plot','-depsc') %Create eps file.
mypdf = eps2pdf('my_plot'); %Should produce mypdf in my current directory.
<error message prints>
This isn't a standard function. If you read the function you will see errStr that it returns for this.
function [ok,errStr] = read_epsfilecontent( epsFile )
% Reads the content of the eps file into epsFileContent
global epsFileContent
ok = 0;
errStr = [];
fh = fopen(epsFile,'r');
if fh == -1
errStr = ['File: ' epsFile ' cannot be accessed or does not exist'];
return
end
Then we figure out when fopen returns -1
fileID = fopen(filename) opens the file, filename, for binary read
access, and returns an integer file identifier equal to or greater
than 3. MATLABĀ® reserves file identifiers 0, 1, and 2 for standard
input, standard output (the screen), and standard error, respectively.
If fopen cannot open the file, then fileID is -1.
Which means please post some of your code so we can figure out why it cannot open your file.
Edit: After some work around and it wasn't necessary to download the code this is how I solved your problem. There is another implementation called eps2xxx
While running your code I received this error
Error while creating temporary eps file: *.eps - File:
C:\Users\Ryan\Documents\MATLAB*.eps cannot be accessed or does not
exist
Which lead me to the information in the documentation here.
% Create tmp file,...
[ok,errStr] = create_tmpepsfile(source,tmpFile,orientation);
if ~ok
status = ['Error while creating temporary eps file: ' epsFile ' - ' errStr];
if nargout, result = 1; end;
if nargout > 1, msg = status; else, disp(status); end;
And I read you needed GhostScript, I wasn't sure if I had this anyways. I downloaded it and gave the full pathway to GS like the following.
figure()
fullgspath = 'C:\Program Files\gs\gs9.23\bin\gswin64c.exe';
plot(linspace(1,100),linspace(1,100)); %Simple line
print('my_plot','-depsc');
eps2xxx('my_plot.eps',{'pdf'},fullgspath);
which created your nice little pdf here.

How to fix error: "A(I): index out of bounds; value 1 out of bound 0"

So I made this function, but I don't know why I'm getting this error. How can I fix it?
error: LOADC: A(I): index out of bounds; value 1 out of bound 0
error: called from
LOADC at line 15 column 13
function res=LOADC(url)
[nomeFicheiro,sucesso]= urlwrite(url,'Composicoes.txt');
ficheiro=fopen(nomeFicheiro,'r');
fgetl(ficheiro);
nLinhas=0;
while (fgets(ficheiro) ~= -1)
nLinhas = nLinhas+1;
end
for i=2:nLinhas
linha=fgetl(ficheiro);
pontovirgula=findstr(linha,';');
Material=linha(1:pontovirgula(1)-1);
for n=1:2:length(pontovirgula)
ElemX=linha(pontovirgula(n)+1:pontovirgula(n+1)-1);
PercentX=linha(pontovirgula(n+1)+1:pontovirgula(n+2)-1);
end
end
fclose(ficheiro);
res=Composicoes;
end
The immediate is you're trying to access a value within an empty array (which has no values in it).
The reason that this is happening is that you read your entire file inside of your first while loop which places the file pointer at the end of the file. Then (without resetting the file pointer), you try to read it line by line in the for loop. Since the file pointer is at the end of the file already, fgetl will always return an empty array ([]) so when you start trying to work with it, you get the indexing error that you've shown.
The solution is one of two options:
Call frewind(ficheiro) before the for loop to reset the file pointer to the beginning of the file so that you can successfully read each line.
Come up with a better way to parse your file rather than looping through the whole file for the sole purpose of counting the number of lines in the file.
If you post some of the file contents we can likely provide you with a better way to parse the file in one or two lines of code.
Update
Also if you look at this line, n goes all the way to the end of pontovirgula.
for n = 1:2:length(pontovirgula)
But then you try to access 1 and 2 past the end of the array
pontovirgula(n+1)
pontovirgula(n+2)
This is going to cause issues for sure. Try only looping until 2 from the end instead.
for n = 1:2:(numel(pontovirgula) - 2)
Update 2
Given that you have posted the file contents, here is an alternate way to parse the file.
fid = fopen('filename.txt', 'rt');
lines = textscan(fid, '%s', 'HeaderLines', 1);
fclose(fid);
% For each line we want to get the reference off of the front
parts = regexp(lines{1}, ';', 'split');
materials = cell(1, numel(parts));
elements = cell(1, numel(parts));
percentages = cell(1, numel(parts));
for k = 1:numel(parts)
% Remove the last empty blank
parts{k}(end) = [];
% Get the material (the first element)
materials{k} = parts{k}{1};
% Get the elements
elements{k} = parts{k}(2:2:end);
% Get the percents
percents{k} = parts{k}(3:2:end);
end
Check the length of linha, and the values of pontovirgula that you are using to index into linha.

How can I read a simple txt file in Matlab in the fortran way (i.e. I want to keep reading after the newline)

I have to read the simple text file I write on the end of this post (it is just a sctructured grid). In fortran it is so easy to do this, you just have to do:
read(fileunit,*)
read(fileunit,*) mc,nc
do j = 1, nc
read (fileunit, *) dummy, dummy, (xcor(j,i), i=1,mc)
enddo
is there an equivalent function in matlab that reads element by element and keeps reading after the newline like in fortran? I could not find it, all the function as fscanf, textscan etc read line by line and then i have to parse each line. Here is the file. thanks for any help A.
Gridfile version 8.675.44
8 3
eta= 1 0.00000000000000000E+00 1.50000000000000000E+02
4.50000000000000000E+02 6.00000000000000000E+02
4.50000000000000000E+02 6.00000000000000000E+02
4.50000000000000000E+02 6.00000000000000000E+02
eta= 2 0.00000000000000000E+00 1.50000000000000000E+02
3.00000000000000000E+02 4.50000000000000000E+02
7.50000000000000000E+02 9.00000000000000000E+02
4.50000000000000000E+02 6.00000000000000000E+02
eta= 3 0.00000000000000000E+00 1.50000000000000000E+02
3.00000000000000000E+02 4.50000000000000000E+02
7.50000000000000000E+02 9.00000000000000000E+02
4.50000000000000000E+02 6.00000000000000000E+02
There are many ways to do this, but perhaps you will like the way fscanf works, as in this example. After the file is opened by something like fin = fopen('gridfile.txt') and the header swallowed, you can use fscanf(f, 'x= %d'), and then fscanf(f, '%f'), which will read the entire block. fscanf does not stop at the end of a line if not instructed to do so. Taken together, a solution could look like
fin = fopen('gridfile.txt');
fgetl(fin);
% read data counts
cnt = fscanf(fin, '%d %d', 2);
mc = cnt(1);
nc = cnt(2);
xcor = zeros(nc, mc);
% read blocks of data
for j = 1 : nc
fscanf(fin, '%s %s', 2);
xcor(j, :) = fscanf(fin, '%f', mc)';
end
fclose(fin);
fscanf keeps matching the format specifier as long as possible, and returns only when no further consecutive matches can be found. The above examples uses this in two places. First, to extract the dimensionality cnt, in your example (8, 3), and second, to read eight consecutive floating point values per record.