Writing txt files accurately with a restriction on the number of columns.
9 vues (au cours des 30 derniers jours)
Afficher commentaires plus anciens
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.
3 commentaires
dpb
le 16 Avr 2023
I was too lazy to write the code, Rik, so didn't think it deserved Answer status... :)
Réponse acceptée
dpb
le 16 Avr 2023
Modifié(e) : dpb
le 16 Avr 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 commentaires
Plus de réponses (2)
Stephen23
le 16 Avr 2023
Modifié(e) : Stephen23
le 16 Avr 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 commentaires
Stephen23
le 17 Avr 2023
Modifié(e) : Stephen23
le 18 Avr 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
le 16 Avr 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 commentaires
dpb
le 16 Avr 2023
I didn't check anything but longer values; seemed to work for that so I'm not sure -- the rounding is probably suspect...
Voir également
Catégories
En savoir plus sur Environment and Settings dans Help Center et File Exchange
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!