Print to eps on Win produces Unix line endings (Bug?) - matlab

On Win7 64b with R2014b, printing a figure to .eps produces Unix line endings (LF or \n). Is this expected or a bug?
Also, does it depend on Matlab version?
You can test with:
% Plot and export to .eps
plot(1:10)
print(gcf,'test','-depsc')
fid = fopen('test.eps');
% Check if Unix LF only
line = fgets(fid);
if all(line(end-1:end) == sprintf('\r\n'))
disp('CRLF')
elseif line(end) == sprintf('\n')
disp('LF only!')
end
% Clean up
fclose(fid);
delete('test.eps')
Edit
Why it matters to me? I am exporting figures to .eps and compiling them with a Miktex 2.9 distribution through epstopdf. However, I get a blank figure and the problem is explained here https://tex.stackexchange.com/questions/208179/epstopdf-error-undefined-in-uagelevel
Now, I was wondering why I never had this issue before. It seems from Louis's answer, it was introduced with the new release and Unix like line endings in the .eps

First off: according to the EPS format specification (large file obtained from here):
Page 26:
The characters carriage return (CR) and line feed (LF) are also called newline
characters. The combination of a carriage return followed immediately by a line
feed is treated as one newline.
Page 74:
The PostScript language scanner and the readline operator recognize all three external
forms of end-of-line (EOL)—CR alone, LF alone, and the CR-LF pair—
and treat them uniformly, translating them as described below.
So both forms could actually be used.
I think your test is wrong. You separate lines with textscan according to '\n'; but that doesn't exclude '\r\n' (you will split lines according to '\n', and '\r' will remain as the last character of each line).
I suggest you test this way:
fid = fopen('test.eps');
s = fread(fid); %// read whole file as a vector of ASCII codes
LF = find(a==10); %// find locations of LF
CR = find(a==13); %// find locations of CR
if all(ismember(LF-1,CR)) %// test if every LF is preceded by a CR
disp('Every LF is preceded by a CR')
end
On my Windows system (Matlab 2010b, Windows Vista 32 bits) it turns out that indeed every LF is preceded by a CR, so Windows-like line endings are used.

Related

how to read binary format byte by byte in MATLAB

I have been struggling with this bug. When using MATLAB to read a binary file that contains three columns of numbers in float formats.
I am reading one number at a time using this line.
pt(j) = fread(fid,1,'float','a');
I have found that sometimes (rarely) MATLAB instead of reading four bytes for a float, it uses 5 bytes. And it misses up the rest of the reading. I am not sure if the file is corrupted or MATLAB has a bug there. When I printed the file as a txt and read it in txt everything works well.
As a work around here is what I did:
cur = ftell(fid);
if (cur - prev)~= 4
pt(j) = 0; % I m throwing this reading away for the sake of saving the rest of the data. This is not ideal
cur = prev +4;
fseek(fid, cur,'bof');
end
prev = cur;
I tried different combinations of different formats float32 float64 etc... nothing works MATLAB always read 5 bytes instead of 4 at this particular location.
EDIT:
To solve it based on Chris's answer. I was using this command to open the file.
fid = fopen(fname,'rt');
I replaced it with this
fid = fopen(fname,'r');
Sometimes, rarely, skipping a byte. It sounds to me like you are on Windows, and have opened the file in text mode. See the permissions parameter to the fopen function.
When opening a file in text mode on Windows, the sequence \r\n (13,10) is replaced with \n (10). This happens before fread gets to it.
So, when opening the file, don't do:
fid = fopen('name', 'rt');
The t here indicates "text". Instead, do:
fid = fopen('name', 'r');
To make this explicit, you can add b to the permissions. This is not documented, but is supposed to mean "binary", and makes the call similar to what you'd do in C or in the POSIX fopen():
fid = fopen('name', 'rb');

strange behavior of the fscanf function

I am trying to read the information contained in a small configuration file with Matlab's fscanf function. The content of the file is;
YAcex: 1.000000
YOx: 1.000000
KAce: 1.000000
The matlab code used to parse the file is;
fh = fopen('parameters', 'r');
fscanf(fh, 'YAcex: %f\n')
fscanf(fh, 'YOx: %f\n')
fscanf(fh, 'KAce: %f\n')
fclose(fh);
When this script is invoked, only the "YAcex" line is read correctly; fscanf returns [] for the two other lines. If the YOx and KAce lines are switched (KAce before YOx), all lines are read correctly by fscanf.
Can someone explain this behavior?
supplementary information: The linefeeds in the input file are simple linefeed (\n character, without \r character).
Your problem is that you only want to read one value per call to fscanf, but by default it tries to read as many values as possible. Note this excerpt from the documentation:
The fscanf function reapplies the format throughout the entire file and positions the file pointer at the end-of-file marker. If fscanf cannot match formatSpec to the data, it reads only the portion that matches and stops processing.
This means the first call correctly reads the first line of the file, but then tries to read the next line as well, finding no exact match to its format specifier. It finds a partial match for the next line, where the first Y of YOx: matches the beginning of YAcex: in the format specifier. This partial match places the file pointer directly after the Y in YOx:, causing the next call to fscanf to fail since it is starting at the Ox: .... We can illustrate this with ftell:
fh = fopen('parameters', 'r');
fscanf(fh, 'YAcex: %f\n');
ftell(fh)
ans =
18 % The "O" is the 18th character in the file
When you switch the YOx: and KAce: lines, a partial match of the next line doesn't happen any more, so the file pointer ends up at the beginning of the next line every time and all the reads are successful.
So, how can you get around this? One option is to always specify the size argument so fscanf doesn't reapply the format specifier unnecessarily:
fh = fopen('parameters', 'r');
fscanf(fh, 'YAcex: %f\n', 1);
fscanf(fh, 'YOx: %f\n', 1);
fscanf(fh, 'KAce: %f\n', 1);
fclose(fh);
Another option is to do this all in one line:
fh = fopen('parameters', 'r');
values = fscanf(fh, 'YAcex: %f\n YOx: %f\n KAce: %f\n');
fclose(fh);
And values will be a 3-by-1 array containing the 3 values from the file.
As you already realized, \r or \r\n could cause this kind of behavior. The likely reason is similar to that, for example, there is some invisible characters like space somewhere. You can debug this by reading all as uint8, and take a look at the location where problem occurs:
u8 = fread(fh, inf, '*uint8')';
One stupid way to avoid this kind of issue is to read all as char, and search each keyword:
fh = fopen('parameters');
ch = fread(fh, inf, '*char')'; % read all as char
fclose(fh);
YAcex = regexp(ch, '(?<=YAcex:\s?)[\d\.]+', 'match', 'once'); % parse YAcex
You can parse others accordingly. The advantage of this is that it is less sensitive to a space somewhere, and the order of parameters does not matter.

why textscan only read one line

I am trying to read a csv file use textscan. The fields are seperated with ',' . I used the following code, but it only read in one line of data into the matrix W.
I also tried dlmread(), it got the number of fields wrong.
The file is contructed under linux, matlab is under linux.
file_id = fopen('H:\data\overlapmatrices\cos.mat.10');
W = textscan(file_id, '%f', 'delimiter', ',' , 'EndOfLine', '\r\n');
fclose(file_id);
clear file_id;
you might wanna try csvread, it should do the trick.
or you could alway do something dirty like
fid = fopen( filename );
tline = fgetl(fid);
while ischar(tline) %or some other check
%sscanf(tline...
tline = fgetl(fid);
end
The problem could be in how the end of line is represented in the file (see also this article on Wikipedia). While \r\n (the combination of a carriage return and a newline character) is common on Windows, \n (just the newline character) is the standard on Linux and other Unix systems.
But as ben is saying, csvread might be an easier way how to read the file.

Char (non ascii) in Matlab

I have three characters (bigger than 127) and I need to write it in a binary file.
For some reason, MATLAB and PHP/Python tends to write a different characters.
For Python, I have:
s = chr(143)+chr(136);
f = open('pythonOut.txt', 'wb');
f.write(s);
f.close();
For MATLAB, I have:
s = strcat(char(143),char(136));
fid = fopen('matlabOut.txt');
fwrite(fid, s, 'char');
fclose(fid);
When I compare these two files, they're different. (using diff and/or cmp command).
More over, when I do
disp(char(hex2dec('88'))) //MATLAB prints
print chr(0x88) //PYTHON prints ˆ
Both outputs are different. I want to make my MATLAB code same as Python. What's wrong with MATLAB code?
You're trying to display extended ASCII characters, i.e symbols with an ASCII number greater than 128. MATLAB does not use extended ASCII internally, it uses 16-bit Unicode instead.
If you want to write the same values as in the Python script, use native2unicode to obtain the characters you want. For example, native2unicode(136) returns ^.
The fact that the two files are different seems obvious; chr(134) is obviously different from char(136) :)
In Matlab, only the first 127 characters correspond to (non-extended) ASCII; anything after that is Unicode16.
In Python, the first 255 characters correspond to (extended) ASCII (use unichr() for Unicode).
However, unicode 0x88 is the same as the extended ASCII 0x88 (as are most of the others). The reason Matlab does not display it correctly, is due to the fact that the Matlab command window does not treat Unicode very well by default, while Python (running in a terminal or so I presume) usually does a better job.
Try changing the font in Matlab's command window, or starting Matlab in a terminal and print the 0x88 character; it should be the same.
In any case, the output of the characters to file should not result in any difference; it is just a display issue.

Displaying information from MATLAB without a line feed

Is there any way to output/display information from a MATLAB program without an ending line feed?
My MATLAB program outputs a number a bit now and then. Between outputting the number the program does a lot of other stuff. This is a construct mainly to indicate some kind of progress and it would be nice not to have a line feed each time, just to make it more readable for the user. This is approximately what I'm looking for:
Current random seed:
4 7 1 1
The next output from the program would be on the same row if it is still doing the same thing as before.
I've read the doc on disp, sprintf, and format but haven't found what I'm looking for. This doesn't mean it isn't there. ;)
The fprintf function does not add a line feed unless you explicitly tell it to. Omit the fid argument to have it print to the Command Window.
fprintf('Doing stuff... ');
for i = 1:5
fprintf('%d ', i);
% do some work on that pass...
end
fprintf(' done.\n'); % That \n explicitly adds the linefeed
Using sprintf won't quite work: it creates a string without a line feed, but then if you use disp() or omit the semicolon, disp's own display logic will add a line feed.