Writing txt files accurately with a restriction on the number of columns.
9 visualizaciones (últimos 30 días)
Mostrar comentarios más antiguos
Ali Almakhmari
el 16 de Abr. de 2023
Okay. So I am having kind of a weird problem. I am trying to write a bunch of txt files where I have some vectors (arrays) and I print/write them in txt files using fprintf. And you know when you go into Notepad to edit a txt file and you see at the right bottom corner of the program where it says "Ln X, Col Y" where it reports which line and column the cursor is in? Well, I have a restriction where I CANNOT write information in Col that is greater than 50. So if I reach Col 50, I need to move to the next line. The problem is when I have a vector like [0,0,1,2.14,3] and lets say I reached column 50 in the fourth element of the array, I cannot simply fprintf it like this:
0,0,1,2.1
4,3
It will come out weird. I have to code it such that MATLAB knows that it will reach the 50 column and stops printing the number at the current line before moving to the next line:
0,0,1,
2.14,3
I hope I described the problem accurately for someone to help me implement this in MATLAB. Thank you.
Respuesta aceptada
dpb
el 16 de Abr. de 2023
Editada: dpb
el 16 de Abr. de 2023
a=randi(200,[1,25]);
fmt=['%d' repmat(',%d',1,numel(a)-1)];
s=sprintf(fmt,a)
LL=25;
L=strlength(s)
O=[];
while L>0
I=strfind(s,','); % locate the delimiters
J=I(find(I<=LL,1,'last')); % get the last one within line length limit
O=[O;string(s(1:J))]; % add that to the output array
s=s(J+1:end); % get the rest of the string
L=strlength(s); % recompute the length remaining
if L<=LL % handle last line w/o trailing comma
O=[O;string(s)];
L=0;
end
end
O
Now you can write the output string array with writematrix or you could echo out each line during the loop with the venerable fprintf but that requires you explicitly open/close the file.
The above seemed to get pretty klunky; I'm sure it could be optimized "more better", but seems to work ok.
"LL" is, of course, the line-length limit; set as wish...
0 comentarios
Más respuestas (2)
Stephen23
el 16 de Abr. de 2023
Editada: Stephen23
el 16 de Abr. de 2023
V = randi(123,1,23)
T = sprintf('%g,',V);
U = regexprep(T,'(.{1,13}),','$1\n'); % e.g. max 13 columns
fprintf('%s',U)
And if you want to include the trailing comma:
U = regexprep(T,'.{1,12},','$&\n'); % e.g. max 13 columns
fprintf('%s',U)
Note that any single values longer than the requested column limit will not be broken over two lines.
4 comentarios
dpb
el 17 de Abr. de 2023
Editada: dpb
el 17 de Abr. de 2023
5 columns of %3d would be 20 characters counting the comma; the same five columns as %12E.5 would be 65; it would depend on the formatting, not the number of columns to ensure didn't pass the character count oun the line...
Now, granted, OP wrote "columns" in the title, but the problem description is actually counting characters
Stephen23
el 17 de Abr. de 2023
Editada: Stephen23
el 18 de Abr. de 2023
"but the problem description is actually counting characters"
Correct, but for MS Notepad the "Col #" value as the OP described is a count of characters (sort of):
"this counts/limits columns not characters, correct?"
Ummm.... For MS Notepad the two are basically equivalent: the "Col #" is actually the number of the column which will get printed in at the given cursor location (note Notepad++ also uses this definition). This matches what the OP described and what my code does. You appear to be using another definition of "column", which so far you have not explicitly described.
"5 columns of %3d would be 20 characters counting the comma; the same five columns as %12E.5 would be 65"
Aaaha, so you are using your own, different definition of "column".
It appears that you are thinking of "column" in terms of something like the fields per line of a CSV file, but I do not see this definition as matching what the OP described, nor the behavior of my code, nor does it match what MS Notepad provides with the "Col #" value (see OP's question above and also the MS Notepad screenshot). The OP explicitly referred to the the MS Notepad context and meaning.
Still, not very relevant for my code, which limits the columns (as MS Notepad and the OP consistently use the term, or equivalently the number of characters) per line.
"this counts/limits columns not characters, correct?"
So it appears the answer to your very first question is "no, not as you use the term".
In any case, I presume that a simple test would also resolve your question:
V = randi(123,1,23)
T = sprintf('%12e5,',V);
U = regexprep(T,'(.{1,20}),','$1\n'); % e.g. max 20 columns
fprintf('%s',U)
dpb
el 16 de Abr. de 2023
Still with same idea but a little cleaner implementation...
%a=randi(200,[1,25]);
%fmt=['%d' repmat(',%d',1,numel(a)-1)];
%s=sprintf(fmt,a)
s = '169,69,96,41,196,14,77,27,21,47,155,58,60,100,37,168,68,126,49,189,136,70,85,95,76'
LL=25; % max line length
I=strfind(s,','); % breakpoints
for i=I(fliplr(find(diff(ceil(strfind(s,',')/(LL-1)))))) % insert from back to front
s=insertAfter(s,i,newline);
end
s
strfind(s,newline) % all \n < LL*l where l is line number
2 comentarios
Stephen23
el 16 de Abr. de 2023
Editada: Stephen23
el 16 de Abr. de 2023
The last line does not seem to be split correctly, it always includes the two last values:
s = '123,456,789'
LL=4; % max line length
I=strfind(s,','); % breakpoints
for i=I(fliplr(find(diff(ceil(strfind(s,',')/(LL-1)))))) % insert from back to front
s=insertAfter(s,i,newline);
end
disp(s)
dpb
el 16 de Abr. de 2023
I didn't check anything but longer values; seemed to work for that so I'm not sure -- the rounding is probably suspect...
Ver también
Categorías
Más información sobre Environment and Settings en Help Center y File Exchange.
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!