fprintf uiputfile of multiselect data file doesnt work....

조회 수: 1 (최근 30일)
Tyann Hardyn
Tyann Hardyn 2021년 8월 13일
편집: Tyann Hardyn 2021년 8월 20일
Hi, everyone.... I just so confused with this data, so let me share my wrongness code right below :
[namafile,direktori]=uigetfile({'*.txt', 'Text-files (*.txt)'},'Load Data Magnet LEMI Non RAW Non IAGA (Menitan / Detikan)','Multiselect','on');
full = fullfile(direktori,namafile);
nfiles = size(full,2);
f = cellstr(fullfile(direktori,namafile));
file = length(f);
if file == 1
[~, base, ~] = fileparts(full);.... %This completed code was good
else
if file > 1 %This is my code for multiselect file from uigetfile function
for k = 1:nfiles
[~, namafile{k}] = fileparts(full{k});
nama = namafile{k};
lastIndex2 = length(nama);% Capitalize first character and lower case remaining characters.
m1 = contains(nb, '1m');
s1 = contains(nb, '1s');
lem = contains(nb, 'lemi');
sta = extractBefore(nb,"_lemi");
sti2 = "Hasil Ekstrak Gabungan File Komponen Magnet H dan F Data Lemi" + " " + "(" + tipe2 + ")" + " " + "Stasiun" + " " + sta2 ;
opts = delimitedTextImportOptions('Delimiter',' ',...
'VariableNames', {'VarName1','VarName2','VarName3','VarName4','VarName5','VarName6','VarName7','VarName8','VarName9','VarName10','VarName11','VarName12','VarName13'},...
'WhiteSpace', '');
B = readmatrix(full{k}, opts);
tahun = cellfun(@str2num,(B(1:end,1))); %: Mendapatkan data tahun pada kolom 1
bulan = cellfun(@str2num,(B(1:end,2))); %: Mendapatkan data bulan pada kolom 2
tanggal = cellfun(@str2num,(B(1:end,3))); %: Mendapatkan data tanggal pada kolom 3
jam = cellfun(@str2num,(B(1:end,4))); %: Mendapatkan data jam pada kolom 4
menit = cellfun(@str2num,(B(1:end,5))); %: Mendapatkan data menit pada kolom 4
detik = cellfun(@str2num,(B(1:end,6))); %: Mendapatkan data detik pada kolom 6
x = cellfun(@str2num,(B(1:end,7))); %: Mendapatkan data magnet arah sumbu x pada kolom 7
y = cellfun(@str2num,(B(1:end,8))); %: Mendapatkan data magnet arah sumbu y pada kolom 8
z = cellfun(@str2num,(B(1:end,9))); %: Mendapatkan data magnet arah sumbu z pada kolom 9
h = cellfun(@str2num,(B(1:end,10))); %: Mendapatkan data medan magnet Komponen H pada kolom 10
h_combine(:,k) = h(:);
h = h(:);
D = datetime(tahun,bulan,tanggal,0,0,0,'TimeZone','Asia/Jakarta');
D_combine(:,k) = D(:);
D = D(:);
date = string(D_combine(:));
time = hours(jam) + minutes(menit) + seconds(detik);
time.Format = 'hh:mm:ss';
time_combine(:,k) = time(:);
time = time(:);
tim = string(time);
wak = D + time;
wak_combine(:,k) = wak(:);
wak = wak(:);
waks = wak_combine(:,1:k);
waks = waks(:);
ntropy = string(waks);
DOHk = sqrt((x.^2)+(y.^2));
DOHk_combine(:,k) = DOHk(:);
DOHk = DOHk(:);
komph = DOHk_combine(:,1:k);
komph(:) = double(komph(:));
DOFk = sqrt((x.^2)+(y.^2)+(z.^2));
DOFk_combine(:,k) = DOFk(:);
kompf = DOFk_combine(:,1:k);
kompf(:) = double(kompf(:));
output_combine2 = horzcat(DOHk_combine(:),DOFk_combine(:));
%Im trying to let the variable become so many like that because im still trying and error...
end
if m2 == 1 || s2 == 1 || lem2 == 1
[namafile3, direktori1, ~] = uiputfile({'*.txt', 'Text-files (*.txt)'}, 'Simpan Hasil Sebagai', sti2);
eval(['cd ''' direktori1 ''';']);
fout=fopen(namafile3,'w');
fprintf(fout,'%s %f %f\n',ntropy, komph(:), kompf(:));% This is the [expletive deleted--dpb] output that brings me so confused
fclose(fout);
end
end
This output of " fprintf(fout,'%s %f %f\n',ntropy, komph(:), kompf(:)); ", just bring me so confused because although the length of ntropy, komph(:), and kompf(:) variables are matched each other, no matter how hard i try, it always give this terrible output :
02-Jul-2019 00:00:59 NaN NaN
02-Jul-2019 00:03:59 NaN NaN
02-Jul-2019 00:06:59 NaN NaN
02-Jul-2019 00:09:59 NaN NaN
02-Jul-2019 00:12:59 NaN NaN
02-Jul-2019 00:15:59 NaN NaN
02-Jul-2019 00:18:59 NaN NaN
........................
Why it always give me the NaN???? it should be a double variable data, right? So, would anyone lend me a hand to solve my problem here?? Thank you very much. (I have attached my data sample for anyone who wanna try my data with my code...)
Im sorry for interrupt your days... /.\ /.\ /.\
  댓글 수: 2
Stephen23
Stephen23 2021년 8월 13일
You should replace this evil EVAL (and command syntax):
eval(['cd ''' direktori1 ''';']);
with simpler and more efficient function syntax:
cd(direktori1)
Or even better: use absolute/relative filenames instead of slow CD.
Tyann Hardyn
Tyann Hardyn 2021년 8월 13일
Alright, yes, thats solve a bit of my problem... Everyone in forum always do the same advice to me, i just forgot about that. Thank you very much, Sir...

댓글을 달려면 로그인하십시오.

채택된 답변

Cris LaPierre
Cris LaPierre 2021년 8월 13일
편집: Cris LaPierre 2021년 8월 13일
The issue is with how MATLAB is plugging numbers into your format spec '%s %f %f\n'. When you supply fprintf with more than 1 variable, and those variables are not scalars, it uses all the values from the first variable before moving to values from the second variable. In this case, notice that the first time in your oput is '02-Jul-2019 00:00:59' but the second is '02-Jul-2019 00:03:59'. The 2nd and 3rd ntropy values (01:59 and 02:59) were written using %f, but the data is string, so you get NaN displayed.
The solution is to either put the fprintf statement inside a for loop that writes a single value from each variable each time,
for v = 1:length(ntropy)
fprintf(fout,'%s %f %f\n',ntropy(v), komph(v), kompf(v));
end
or organize your data so that it is formatted in a way where the format string aligns with the data. Since MATLAB uses column-major ordering by default, this means putting each variable in a matrix row so that as the data is read out column by colum, the 3 rows align with the 3 formats.
fprintf(fout,'%s %f %f\n',[ntropy, komph, kompf]');
  댓글 수: 7
Tyann Hardyn
Tyann Hardyn 2021년 8월 14일
@Cris LaPierre "The issue is with how MATLAB is plugging numbers into your format spec '%s %f %f\n'. When you supply fprintf with more than 1 variable, and those variables are not scalars, it uses all the values from the first variable before moving to values from the second variable. In this case, notice that the first time in your oput is '02-Jul-2019 00:00:59' but the second is '02-Jul-2019 00:03:59. The 2nd and 3rd ntropy values (01:59 and 02:59) were written using %f, but the data is string, so you get NaN displayed."
Ohhh, so thats why the output is always give me NaN .... I have already know the reason now.... Thank you so much, Sir... Its become my new knowledge...
Tyann Hardyn
Tyann Hardyn 2021년 8월 20일
편집: Tyann Hardyn 2021년 8월 20일
@Cris LaPierre Ohh, yes, you re right, Sir. I have a problem with that order of data. And i remember that i ever ask about it in this question. So i try again what you share to me, and its work also by using this code !!!
fprintf(fout,'%s %f %f\n',[ntropy, komph, kompf]');
Without the code of yours, my previous code is :
fprintf(fout,'%s %s %s %s %s %s %s %s\n', 'DATE', 'TIME', 'H(Calc)', 'H(Obs)', 'F(Calc)', 'X(Obs)', 'Y(Obs)', 'Z(Obs)');
fprintf(fout,'%s %s %.2f %.2f %.2f %.2f %.2f %.2f\n', char(D), times, DOH, h, DOF, x, y, z);
fclose(fout);
And it brings me the confused output with NaN thing.
After that, i retype again by using your format so the code above become like this :
fprintf(fout,'%s %s %s %s %s %s %s %s\n', 'DATE', 'TIME', 'H(Calc)', 'H(Obs)', 'F(Calc)', 'X(Obs)', 'Y(Obs)', 'Z(Obs)');
fprintf(fout,'%s %s %.2f %.2f %.2f %.2f %.2f %.2f\n', [char(D), times, DOH, h, DOF, x, y, z]');
fclose(fout);
And voila, it Work!! Thank you very much, Sir
So, matlab is indeed, a column based script.

댓글을 달려면 로그인하십시오.

추가 답변 (1개)

dpb
dpb 2021년 8월 13일
편집: dpb 2021년 8월 13일
fprintf(fout,'%s %f %f\n',ntropy, komph(:), kompf(:));% This is the [expletive deleted--dpb] output that brings me so confused
The problem is that fprintf is vectorized and outputs each argument in its entirety before going on to the next and tries to match the elements in sequence to the formatting string. Your output string says it expects one string and then two floats in sequence but it is passed an array of strings, then an array of double, then another array of double.
Low level i/o has to be written a record at a time -- something like
[namafile3, direktori1, ~] = uiputfile({'*.txt', 'Text-files (*.txt)'}, 'Simpan Hasil Sebagai', sti2);
fout=fopen(fullfile(direktori1,namafile3),'w');
for i=1:numel(komph)
fprintf(fout,'%s %f %f\n',ntropy(i),komph(i),kompf(i));
end
fclose(fout);
There are examples of outputting formatted text files in the documentation for fprintf that illustrate this.
Mixed data types are more difficult to deal with than consistent types that can be put into single arrays.
You might want to look into using the table data structure instead; writetable then will handle the various data types transparently for you.
NOTA BENE:
I've not looked at the rest of the code, but almost certainly most of the machinations could be avoided by reading the variables as the proper type. See detectImportOptions and readtable
Also, as the logic is presently, there is nothing happening for the case of trying to read one file.
  댓글 수: 2
Tyann Hardyn
Tyann Hardyn 2021년 8월 14일
Yea, thank you for your explanation, Sir. I never think about the use of " numel " before. This is one of the best solution of my problem here.... Thank you so much^^
dpb
dpb 2021년 8월 14일
편집: dpb 2021년 8월 14일
" I never think about the use of " numel " before"
It and size are the two workhorses -- length, while handy and by the name seemingly the proper function, is very dangerous/error-prone and should be avoided in general practice. The reason is that it is defined as
max(size(x))
and so for a 2D array will return either the number of rows if the array is "taller" than "wide" but will return the number of columns if the array is "wider" than "tall".
For a vector, they turn out to be the same, of course, but still it will be either the number of columns if a row vector or number of rows if column vector. It is the same number as numel() for the vector, but in general, length can lead to a surprise on occasion.
"This is one of the best solution of my problem here..."
It is the "plain vanilla" solution and doesn't rely on any of the newer features such as compose that could be used as others have illustrated.
I've not tried to compare the performance of the direct i/o in the loop as above to the vectorized creation of the string array and then outputting it. For relatively small arrays I'm sure either as adequate; if the size grew to be really large I'd guess one would be able to see the difference and the direct use of the runtime i/o libraries would win over the preprocessing-first route.

댓글을 달려면 로그인하십시오.

카테고리

Help CenterFile Exchange에서 Data Type Conversion에 대해 자세히 알아보기

Community Treasure Hunt

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

Start Hunting!

Translated by