Error writing a cell to a text file having numerical value separated by space

3 views (last 30 days)
I am facing a problem writing a cell array of 15 x 105 which must be written to a text fle.
I am attaching my sample file, and my code here.
My code is as follows
clc; clear all; close all;
format long g
fid =fopen('SAVE','r')
% fclose(fid);
tline = fgetl(fid);
k = 1;
while ischar(tline)
%// Store in a cell array
A{k}=strsplit(tline," ");
tline = fgetl(fid);
k = k+1;
end
siz1 = cellfun(@size, A, 'UniformOutput', false);
Lsize1=cellfun(@max,siz1, 'UniformOutput', false);
UNIQ1=unique(cell2mat(Lsize1));
Eleven1 = find(cellfun(@(x) x==11 ,Lsize1));
Twelve1 = find(cellfun(@(x) x==12 ,Lsize1));
Thirteen1 = find(cellfun(@(x) x==13 ,Lsize1));
for i=1:length(A)
for j=1:(length(A{i})-1)
if isempty(A{1,i}{1,j})
fprintf(' Yes Element is Empty\n')
A{1,i}(1)=[];
else
fprintf('Element name is full\n')
end
end
end
siz2 = cellfun(@size, A, 'UniformOutput', false);
Lsize2=cellfun(@max,siz2, 'UniformOutput', false);
Eleven2 = find(cellfun(@(x) x==11 ,Lsize2))
Twelve2 = find(cellfun(@(x) x==12 ,Lsize2))
Thirteen2 = find(cellfun(@(x) x==13 ,Lsize2))
UNIQ2=unique(cell2mat(Lsize2))
for i=1:length(Twelve2)
C1=A{1,Twelve2(i)}{1,1};
L1=length(A{1,Twelve2(i)}{1,1});
C2=A{1,Twelve2(i)}{1,2};
C={C1 C2};
del=' '
A{1,Twelve2(i)}{1,1}=strjoin(C,del);
%using simple parenthesis to set cell array to zero, with note: single index, ie., 2
A{1,Twelve2(i)}(2)=[];
end
siz3 = cellfun(@size, A, 'UniformOutput', false);
Lsize3=cellfun(@max,siz3, 'UniformOutput', false);
Eleven3 = find(cellfun(@(x) x==11 ,Lsize3))
Twelve3 = find(cellfun(@(x) x==12 ,Lsize3))
Thirteen3 = find(cellfun(@(x) x==13 ,Lsize3))
UNIQ3=unique(cell2mat(Lsize3))
S = [ A{:} ]
V = reshape(S,15,[])
disp(V)
% convert to numbers, where possible:
temp = str2double(V);
is_number = ~isnan(temp);
V(is_number) = num2cell(temp(is_number))
% ...
% make modifications to V, as desired
% ...
V{2,2} = 0.7 % (for example)
% write a new file with the modified V:
fid = fopen('Modified.txt','w');
fprintf(fid,'%5s %14.8E %-s %-s %10s %6s %-13s %14.8E %14.8E %14.8E %14.8E\n %19.13E %19.13E %19.13E %19.13E\n',V{:});
fclose(fid);
% view the new file's contents:
type Modified.txt
The reason for error is the space in the numbers making the first entry of each column(highlighted in red), see below screenshot

Accepted Answer

dpb
dpb on 16 Jan 2023
OK revisitng with the previous comments -- as thought, using the MATLAB fixed-width import object makes things much simpler to deal with. Try
opt=detectImportOptions('SAVE01.txt'); % return fixed-width import object; assume no split records
tA=readtable('SAVE01.txt',opt); % import as table with import object
above (after I wrote the input file from that posted without the presumed spurious linefeeds) results in--
>> head(tA)
ans =
8×15 table
Var1 Var2 Var3 Var4 Var5 Var6 Var7 Var8 Var9 Var10 Var11 Var12 Var13 Var14 Var15
_______ _______ ________ ______ __________ __________ _____ ________ ________ ________ _____ _________ __________ ______ ______
{'4' } 0.40039 {'Aqu:'} {'P,'} {'X_m_A,'} {'X_i_A,'} {'T'} 1.16e-15 1.16e-15 1.16e-15 0.4 1.285e+07 6.6714e-15 0.0305 14.645
{'75' } 0.40039 {'Aqu:'} {'P,'} {'X_m_A,'} {'X_i_A,'} {'T'} 1.16e-15 1.16e-15 1.16e-15 0.4 1.285e+07 6.6704e-15 0.0305 14.645
{'1 0'} 0.40039 {'Aqu:'} {'P,'} {'X_m_A,'} {'X_i_A,'} {'T'} 1.16e-15 1.16e-15 1.16e-15 0.4 1.285e+07 6.6704e-15 0.0305 14.645
{'1 1'} 0.40039 {'Aqu:'} {'P,'} {'X_m_A,'} {'X_i_A,'} {'T'} 1.16e-15 1.16e-15 1.16e-15 0.4 1.285e+07 6.6704e-15 0.0305 14.645
{'1 2'} 0.40039 {'Aqu:'} {'P,'} {'X_m_A,'} {'X_i_A,'} {'T'} 1.16e-15 1.16e-15 1.16e-15 0.4 1.285e+07 6.6704e-15 0.0305 14.645
{'1 3'} 0.40039 {'Aqu:'} {'P,'} {'X_m_A,'} {'X_i_A,'} {'T'} 1.16e-15 1.16e-15 1.16e-15 0.4 1.285e+07 6.6704e-15 0.0305 14.645
{'1 4'} 0.40039 {'Aqu:'} {'P,'} {'X_m_A,'} {'X_i_A,'} {'T'} 1.16e-15 1.16e-15 1.16e-15 0.4 1.285e+07 6.6704e-15 0.0305 14.645
{'1 5'} 0.40039 {'Aqu:'} {'P,'} {'X_m_A,'} {'X_i_A,'} {'T'} 1.16e-15 1.16e-15 1.16e-15 0.4 1.285e+07 6.6704e-15 0.0305 14.645
>>
With all the numeric columns already converted on input for you and the first column the sequencing field with the embedded blanks as needed.
Now you can modify the numeric values to your heart's content by referencing whichever column they're in as the VarN table variable.
Unfortunately, TMW has built the import object tool, but it has not done anything about higher level export of mixed types letting you define a top-level format including field width and numeric format so you'll still have to convert the table to a cell array and then use low-level i/o with fprintf to rewrite the output file in the proper form. However, while I didn't look at it closely, it looks like you have already gotten that working as desired.
The key here is, as said, import the file as fixed-width; it then gives you the 15 columns you want/expect and converts the numeric data on input. This can be done w/ textscan or fscanf, too, of course, but it's simpler this way.
  4 Comments
SHADMAN HASAN
SHADMAN HASAN on 18 Jan 2023
Edited: SHADMAN HASAN on 18 Jan 2023
Hi @dpb How do i accept your answer, i don't see the link
the file contains four rows and not two.
Hence, i have to process these 4 lines, as shown
4 4.00391406E-01 Aqu: P, X_m_A, X_i_A, T 0.11600000E-14 0.11600000E-14 0.11600000E-14 0.40000000E+00
1.2850440232187E+07 6.6714382737094E-15 3.0500000000000E-02 1.4644900801657E+01
75 4.00391406E-01 Aqu: P, X_m_A, X_i_A, T 0.11600000E-14 0.11600000E-14 0.11600000E-14 0.40000000E+00
1.2850440226474E+07 6.6703644497117E-15 3.0500000000000E-02 1.4644900812901E+01
However, I gor what i wanted, I used num2str and looped it over the first row, containing numbers with space and wrote them to the file as a string. I am mighty thnakful for your help as it helped me acheive my goal. Thanks again
dpb
dpb on 18 Jan 2023
Edited: dpb on 18 Jan 2023
"The file contains four rows and not two. "
Then use the first solution that joins the two alternate records.
The fixed-width file format is broken with the alternating sub-record format.
Or, preprocess the files to create an unbroken record one first...if the consumer of the file is a Fortran application (as the construction of those looks like just might be), then Fortran input scanning will continue on to finish the input data expected automagically.

Sign in to comment.

More Answers (1)

dpb
dpb on 14 Jan 2023
I'd do the conversion first, then make whatever mods are desired...I'm assuming the file has been corrupted by the display artifact used to post it in that it has a line break between the records; if that isn't present in the original, then the join operation won't be wanted...
S=readlines('SAVE.txt'); % read as string array
S=join([S(1:2:end) S(2:2:end)],' '); % remove the line break if present
C=char(S); % convert to char() array so can...
W=[6 31 37 60 87:15:132 153:20:193]; % locations of fixed field terminations
C(:,W)=','; % introduce field delimiters only where wanted
S=split(string(C),','); % only now break it into the 15 fields
S(:,1)=strrep(S(:,1),' ','').'; % remove the embedded blanks in first field, transpose
It looks to me the removal of the blanks in the first field as you've requested is probably not the thing to do; I'm thinking you may be losing distinction between cases by doing so--position may be significant there. Not knowing what the coding stands for, I didn't make any attempt to do anything comprehensive in studying the sequences that are present other than I note down in the middle there's one that contains text besides just a sequence set of digits.
You can do the numeric conversion and then whatever modifications on the values at will then from the above array.
  2 Comments
SHADMAN HASAN
SHADMAN HASAN on 16 Jan 2023
Edited: SHADMAN HASAN on 16 Jan 2023
Hi @dpb i used your code and i like your approach of retaining the spaces which can solve the problem of positioning.
Your solution introduced ,(comma) which changes the formatting of file and hence it wont work.
Also your code removes the space b/w 1 1(1 space 1) and makes it 11)eleven), similarly 1 2 and others.
However, i feel am asypmtotically close to solving this problem.
However, plz allow me to provide the backgroud and objective of editing the "SAVE.txt" file
  1. I cannot change the formatting, the placing is important for each of the variables separated by space
  2. My objective of editing is to only change the numbers/text which appear after the first column.
  3. The first column cannot be changed, no extra space or zero or removing space where it appears in b/w, as shown in original question
So In a nutshell, i am only wanting to change the values after first column and rewrite the text file as it is shown in original file(SAVE.txt)
dpb
dpb on 16 Jan 2023
Edited: dpb on 16 Jan 2023
Tha's a completely different statement of the problem than you gave before -- in it you specifically circled the fields with spaces and said you didn't want them...as I said, I figured the spaces probably were/are significant and that was probably a_bad_idea™.
To use the above code and not remove the spaces, simply expunge the strrep call and you've got the cell array of 15 fields you asked for...but, of course, when you look at that cel content it is going to be a cell string still; it can't be a number in that format containing embedded spaces; that's a nonstarter and keep the two fields together.
The comma was inserted in the record only in order to be able to break the fields where you said you wanted them; there are inconsistent delimiters in the file otherwise; it actually is a fixed-width text file, not delimited; using the MATLAB tools for them would probably be easier route.
So, go back to the beginning and describe the actual problem trying to be solved -- if it is to simply read the numeric part of the file and make changes in those values, and write the file back out again as another fixed-width text file, you're going at it all wrong. If that is the case, then read the file as it is written, modifiy the variables desired and write it back.
You haven't answered the Q? about whether there's an extra line break in the attached file as compared to the original...one would presume there is just looking at the file content. If so, it would be best to reattach the original data file.

Sign in to comment.

Community Treasure Hunt

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

Start Hunting!