Note: It is at best strange that you want _at_least_ 20 characters
instead of _at_most_. You may want to consider specifying ranges
like, say, 20-30 characters to avoid having lines breaking where
they should not.
Something along these lines may get you started:
_______________________________________________________________
#include <stdio.h>
#include <string.h>
#include <stdlib.h> /* Not needed for PrintStringLinewise() */
#define SEPARATORS " ,"
#define WHITESPACES " \n\t\r"
void PrintStringLinewise (const char *string, int linewidth,
int direction)
{
long int maxoffset;
int offset;
const char *searchpos;
direction = (direction < 0) ? -1 : 1;
maxoffset = (long int) strlen(string);
offset = 0;
searchpos = string;
while (offset < maxoffset) {
if ((offset = linewidth) > maxoffset) {
puts(searchpos);
break;
}
while (offset > 0 && searchpos[offset]) {
if (strchr(SEPARATORS, searchpos[offset]))
{
if (direction < 0) {
while (strchr(SEPARATORS, searchpos[offset]))
offset--;
offset++;
}
if (strchr(WHITESPACES, searchpos[offset]))
offset--;
break;
}
offset += direction;
}
if (searchpos[offset])
offset++;
if (offset == 1)
offset = linewidth;
printf("%.*s\n", offset, searchpos);
searchpos += offset;
maxoffset -= offset;
offset = 0;
/* Gobble blanks */
while (*searchpos && strchr(WHITESPACES, *searchpos)) {
maxoffset--;
searchpos++;
}
}
}
int main (int argc, char **argv)
{
int i, linewidth = 23;
const char *teststring =
"Mary had a little lamb,sheep,goat,frog and a couple"
" of other herding animals";
const char *teststring2 =
"veryveryveryveryveryveryveryveryveryveryveryveryvery"
"veryverylongstring";
if (argc>1)
linewidth = atoi(argv[1]);
for (i=1; i<=linewidth; i++)
putchar((i%10)+'0');
putchar('\n');
PrintStringLinewise(teststring, linewidth, -1);
for (i=1; i<=linewidth; i++)
putchar((i%10)+'0');
putchar('\n');
PrintStringLinewise(teststring, linewidth, +1);
for (i=1; i<=linewidth; i++)
putchar((i%10)+'0');
putchar('\n');
putchar('\n');
for (i=1; i<=linewidth; i++)
putchar((i%10)+'0');
putchar('\n');
PrintStringLinewise(teststring2, linewidth, -1);
for (i=1; i<=linewidth; i++)
putchar((i%10)+'0');
putchar('\n');
PrintStringLinewise(teststring2, linewidth, +1);
for (i=1; i<=linewidth; i++)
putchar((i%10)+'0');
putchar('\n');
return 0;
}
_______________________________________________________________
Note: I did not perform any tests apart from the ones visible
in main(), so check whether everything is as it should be.
You also might want to consider whether int/long int are
the appropriate types for linewidth, offset and maxoffset.
Comments are left as exercise to the reader.
strtok() is not what you need for this, simple pointer pushing will do.
Agreed.
NEVER use strtok(), it is rubish left over for historical compatibility.
If you need its functionality, write your own function with proper semantics.
If I know about the limitations of strtok() and if strtok() is
what I need, then I will use it.
However, as most newbies will get a piece of sample code and
"adapt" it for their purposes, yours is probably good advice
for them.
One "good" use of strtok() certainly is obfuscating... ;-)
Cheers
Michael