I'm writing a program that has the possibility of outputting a large amount of text on a single logical line to the console. In that scenario, I would like to wrap the text at word ends so that words are not split on the end of the line:
i.e., the string lorem ipsum dolor sit amet
should print:
lorem ipsum dolor
sit amet
as opposed to
lorem ipsum dolor si
t amet
I wrote the following function
/* print a string, wrapping lines at word breaks */
void
print_long(const char *s, int maxlen)
{
int pos, len;
pos = 0;
while (pos < strlen(s)) {
len = maxlen;
for (int i = maxlen; i > 0; i--) {
if (s[pos + i] == '\n') {
len = i;
break;
}
}
if (len == maxlen) {
for (int i = maxlen; i > 0; i--) {
if (s[pos + i] == ' ') {
len = i;
break;
}
}
}
printf("%.*s\n", len, s + pos);
pos += len + 1;
}
}
This works on my limited test cases, but it seems overly complex and repetitive. I'm also concerned it could break on scenarios that I haven't tested for. How can I shorten this?
Thanks!
Edit: Additional Test Cases
Lorem ipsum from https://lipsum.com/, maxlen = 80.
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Phasellus sed ultricies diam. Sed auctor nisl libero, a rutrum leo dapibus eu. Aliquam sit amet elit enim. Pellentesque pellentesque orci at dolor placerat, vitae eleifend metus bibendum. Pellentesque tristique venenatis orci a dapibus. Suspendisse blandit non lorem eu pulvinar. Fusce commodo vel ligula et porttitor. Duis eget nisl massa.
Integer placerat odio ut sagittis suscipit. Sed placerat bibendum tellus, nec tempus nulla dignissim at. Integer semper laoreet lacinia. Proin vitae volutpat justo, eget maximus erat. Ut lobortis, lectus bibendum ornare cursus, sem enim vehicula felis, vel iaculis mi eros vitae justo. Duis vel auctor massa. Pellentesque tincidunt vehicula ligula, sit amet pharetra metus vestibulum in. Aliquam aliquam viverra vehicula. Quisque fermentum pulvinar massa non tempus. Nulla in magna ante.
Morbi non mattis elit. Donec non sagittis lorem. Donec at commodo turpis. Maecenas quis libero a metus rutrum efficitur. Duis fermentum iaculis erat venenatis porttitor. Cras tortor nibh, commodo in mi a, venenatis commodo ipsum. Donec a elementum massa, nec porttitor tortor. Aenean dignissim tortor eget lacus fringilla, auctor hendrerit turpis hendrerit. Vivamus mattis purus ac malesuada luctus.
Sed ullamcorper arcu consectetur ex interdum semper. Integer blandit risus turpis, tempor porttitor augue porttitor et. Nunc sit amet consequat augue. Nullam malesuada risus eu neque elementum ullamcorper. Morbi volutpat leo vitae lacus sagittis, vel viverra lorem scelerisque. Nulla enim ipsum, cursus accumsan magna quis, imperdiet semper orci. Phasellus nisl dui, vehicula ac venenatis vel, imperdiet vitae tortor. Vestibulum eget consequat urna. Etiam id lectus sed velit dignissim iaculis. Nam ac lacus non nisi feugiat suscipit. Nullam eleifend ultricies sapien, eget faucibus erat sollicitudin in. Phasellus sed tellus id diam interdum iaculis. Curabitur vulputate, ante ut commodo tristique, metus lacus rutrum magna, ut pulvinar orci augue ac orci. Ut a felis libero. Integer mattis magna quis diam blandit, in auctor urna hendrerit.
Curabitur vestibulum ex in erat euismod, in lacinia neque vestibulum. Phasellus bibendum nunc sed nibh aliquam, suscipit fringilla dolor semper. Nulla vel felis scelerisque, iaculis velit in, gravida turpis. Cras dolor lacus, convallis et ex a, rutrum pretium mauris. Nam dapibus interdum ipsum, et scelerisque magna. Pellentesque tincidunt viverra consequat. Ut finibus nibh et enim lacinia, non sagittis felis viverra. Nulla laoreet mollis dui. Fusce erat lacus, bibendum ac urna in, pretium elementum velit.
Shold result in
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Phasellus sed ultricies
diam. Sed auctor nisl libero, a rutrum leo dapibus eu. Aliquam sit amet elit
enim. Pellentesque pellentesque orci at dolor placerat, vitae eleifend metus
bibendum. Pellentesque tristique venenatis orci a dapibus. Suspendisse blandit
non lorem eu pulvinar. Fusce commodo vel ligula et porttitor. Duis eget nisl
massa.
Integer placerat odio ut sagittis suscipit. Sed placerat bibendum tellus, nec
tempus nulla dignissim at. Integer semper laoreet lacinia. Proin vitae volutpat
justo, eget maximus erat. Ut lobortis, lectus bibendum ornare cursus, sem enim
vehicula felis, vel iaculis mi eros vitae justo. Duis vel auctor massa.
Pellentesque tincidunt vehicula ligula, sit amet pharetra metus vestibulum in.
Aliquam aliquam viverra vehicula. Quisque fermentum pulvinar massa non tempus.
Nulla in magna ante.
Morbi non mattis elit. Donec non sagittis lorem. Donec at commodo turpis.
Maecenas quis libero a metus rutrum efficitur. Duis fermentum iaculis erat
venenatis porttitor. Cras tortor nibh, commodo in mi a, venenatis commodo ipsum.
Donec a elementum massa, nec porttitor tortor. Aenean dignissim tortor eget
lacus fringilla, auctor hendrerit turpis hendrerit. Vivamus mattis purus ac
malesuada luctus.
Sed ullamcorper arcu consectetur ex interdum semper. Integer blandit risus
turpis, tempor porttitor augue porttitor et. Nunc sit amet consequat augue.
Nullam malesuada risus eu neque elementum ullamcorper. Morbi volutpat leo vitae
lacus sagittis, vel viverra lorem scelerisque. Nulla enim ipsum, cursus accumsan
magna quis, imperdiet semper orci. Phasellus nisl dui, vehicula ac venenatis
vel, imperdiet vitae tortor. Vestibulum eget consequat urna. Etiam id lectus sed
velit dignissim iaculis. Nam ac lacus non nisi feugiat suscipit. Nullam eleifend
ultricies sapien, eget faucibus erat sollicitudin in. Phasellus sed tellus id
diam interdum iaculis. Curabitur vulputate, ante ut commodo tristique, metus
lacus rutrum magna, ut pulvinar orci augue ac orci. Ut a felis libero. Integer
mattis magna quis diam blandit, in auctor urna hendrerit.
Curabitur vestibulum ex in erat euismod, in lacinia neque vestibulum. Phasellus
bibendum nunc sed nibh aliquam, suscipit fringilla dolor semper. Nulla vel felis
scelerisque, iaculis velit in, gravida turpis. Cras dolor lacus, convallis et ex
a, rutrum pretium mauris. Nam dapibus interdum ipsum, et scelerisque magna.
Pellentesque tincidunt viverra consequat. Ut finibus nibh et enim lacinia, non
sagittis felis viverra. Nulla laoreet mollis dui. Fusce erat lacus, bibendum ac
urna in, pretium elementum velit.
Loremipsumdolorsitamet,consecteturadipiscingelit.Phasellussedultriciesdiam.Seductornislibero,arutrumleodapibus eu. Aliquam sit amet elit enim. Pellentesque pellentesque orci at dolor placerat, vitae eleifend metus bibendum. Pellentesque tristique venenatis orci a dapibus. Suspendisse blandit non lorem eu pulvinar. Fusce commodo vel ligula et porttitor. Duis eget nisl massa.
Integerplaceratodiout sagittis suscipit. Sed placerat bibendum tellus, nec tempus nulla dignissim atInteger emper laoreetcinia.Proinvitaejusto,egeterat.Ut lobortis, lectus bibendum ornare cursus,sem enim vehicula felis,veliaculismi eros vitaejusto. Duisvelauctorssa. Pellentesquetinciduntvehiculaligulasitmetpharetrametusvestibulumin. Aliquamaliquam viverra vehicula. Quisque fermentum pulvinar massa non tempus. Nulla in magna ante.
Morbi non mattis elit. Donec non sagittis lorem. Donec at commodo turpis. Maecenas quis libero a metus rutrum efficitur. Duis fermentum iaculis erat venenatis porttitor. Cras tortor nibh, commodo in mi a, venenatis commodo ipsum. Donec a elementum massa, nec porttitor tortor. Aenean dignissimtortoregetlacusfringilla,auctorhendreritturpishendreritVivamusmattispurusacmalesuadaluctus.
Should result in
Loremipsumdolorsitamet,consecteturadipiscingelit.Phasellussedultriciesdiam.Seductorni
libero,arutrumleodapibus eu. Aliquam sit amet elit enim. Pellentesque
pellentesque orci at dolor placerat, vitae eleifend metus bibendum. Pellentesque
tristique venenatis orci a dapibus. Suspendisse blandit non lorem eu pulvinar.
Fusce commodo vel ligula et porttitor. Duis eget nisl massa.
Integerplaceratodiout sagittis suscipit. Sed placerat bibendum tellus, nec
tempus nulla dignissim atInteger emper laoreetcinia.Proinvitaejusto,egeterat.Ut
lobortis, lectus bibendum ornare cursus,sem enim vehicula felis,veliaculismi
eros vitaejusto. Duisvelauctorssa.
Pellentesquetinciduntvehiculaligulasitmetpharetrametusvestibulumin.
Aliquamaliquam viverra vehicula. Quisque fermentum pulvinar massa non tempus.
Nulla in magna ante.
Morbi non mattis elit. Donec non sagittis lorem. Donec at commodo turpis.
Maecenas quis libero a metus rutrum efficitur. Duis fermentum iaculis erat
venenatis porttitor. Cras tortor nibh, commodo in mi a, venenatis commodo ipsum.
Donec a elementum massa, nec porttitor tortor. Aenean
dignissimtortoregetlacusfringilla,auctorhendreritturpishendreritVivamusmattispur
sacmalesuadaluctus.
The second is identical to the previous case, but spaces are randomly removed to increase word length.
s + pos
is never going to go past the end of the string due to the while loop, and, if the string is properly null-terminated, printf should never go past the bounds either, right? As for a word longer than line length, it should split at maxlen as if there was no wrapping, which is what I observed in testing. Am I misinterpreting my code or what you've said? \$\endgroup\$s[pos + maxlen]
(becausei
starts atmaxlen
) which can be past the end. For long words,len
will bemaxlen
, and you add that +1 to pos so you'll skip a character (the first line of your second example shows this, as you lose an 's'). \$\endgroup\$