Writing txt files accurately with a restriction on the number of columns.

9 vues (au cours des 30 derniers jours)
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:
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:
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... :)

Connectez-vous pour commenter.

Réponse acceptée

dpb le 16 Avr 2023
Modifié(e) : dpb le 16 Avr 2023
fmt=['%d' repmat(',%d',1,numel(a)-1)];
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'
L = 82
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 = 4×1 string array
"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"
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...

Plus de réponses (2)

Stephen23 le 16 Avr 2023
Modifié(e) : Stephen23 le 16 Avr 2023
V = randi(123,1,23)
V = 1×23
100 92 80 37 40 45 41 52 17 30 21 82 10 50 21 29 83 83 118 115 14 75 116
T = sprintf('%g,',V);
U = regexprep(T,'(.{1,13}),','$1\n'); % e.g. max 13 columns
100,92,80,37 40,45,41,52 17,30,21,82 10,50,21,29 83,83,118,115 14,75,116
And if you want to include the trailing comma:
U = regexprep(T,'.{1,12},','$&\n'); % e.g. max 13 columns
100,92,80,37, 40,45,41,52, 17,30,21,82, 10,50,21,29, 83,83,118, 115,14,75, 116,
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)
V = 1×23
101 87 46 96 117 21 36 45 28 100 4 50 117 65 11 119 11 102 80 90 60 69 122
T = sprintf('%12e5,',V);
U = regexprep(T,'(.{1,20}),','$1\n'); % e.g. max 20 columns
1.010000e+025 8.700000e+015 4.600000e+015 9.600000e+015 1.170000e+025 2.100000e+015 3.600000e+015 4.500000e+015 2.800000e+015 1.000000e+025 4.000000e+005 5.000000e+015 1.170000e+025 6.500000e+015 1.100000e+015 1.190000e+025 1.100000e+015 1.020000e+025 8.000000e+015 9.000000e+015 6.000000e+015 6.900000e+015 1.220000e+025

Connectez-vous pour commenter.

dpb le 16 Avr 2023
Still with same idea but a little cleaner implementation...
%fmt=['%d' repmat(',%d',1,numel(a)-1)];
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'
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 =
'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'
strfind(s,newline) % all \n < LL*l where l is line number
ans = 1×3
24 48 74
  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...

Connectez-vous pour commenter.


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!

Translated by