您需要一个类似于以下的算法:
- 将输出行设置为空,行长度设置为零
- 而读取输入行未检测到 EOF
- 如果是函数行,则继续进行下一次循环 while read 循环
- 而不是在当前输入行的末尾
- 在输入行中查找下一个单词(
strtok()
也许,或strcspn()
或strpbrk()
)
- 如果输出行的长度加 1 表示空格加上下一个字的长度大于 60,则打印输出行,将行长度设置为零
- 如果行长度大于零,则添加空格
- 将下一个单词添加到输出行并增加长度
- 如果输出行中有任何内容,请打印
这让您忽略了功能行。或者,您可以刷新当前输出行(如果它不为空),打印函数行,然后转到下一行。
请注意,如果下一个单词是 60 个字符或更长,这不会截断它,或者拆分它;它只会自己占据一条线。你有责任小心没有缓冲区溢出。例如,您可以刷新前一个输出行,打印该单词及其换行符,然后将输出重置为空。或者您可能会拆分单词(但是您会将其中的一部分拆分为适合当前行,其余部分放在下一行,或者只是强制开始到下一行然后拆分?)。如果这个词有 250 个字符长怎么办?
这是上述算法的相当直接的音译。它从标准输入中读取;我拒绝回答有关打开哪个文件名的提示。如果我想处理任意文件,它们将作为参数在命令行上传递。
#include <stdio.h>
#include <string.h>
/*
.function line should not appear in output
*/
/*
WordOfMoreThanSixtyCharacters--WithNaryASpaceInSight--ThoughThereIsPunctuation!
*/
enum { OUT_LENGTH = 60 };
int main(void)
{
char oline[OUT_LENGTH]; // output line
char iline[4096]; // input line
int olength = 0; // length of data in output line
const char separators[] = " \n\t";
while (fgets(iline, sizeof(iline), stdin) != 0)
{
if (iline[0] == '.')
continue;
int wlength; // word length
char *wline = iline; // start of word
wline += strspn(wline, separators);
while ((wlength = strcspn(wline, separators)) > 0)
{
if (olength + 1 + wlength > OUT_LENGTH)
{
printf("%.*s\n", olength, oline);
olength = 0;
if (wlength >= OUT_LENGTH)
{
printf("%.*s\n", wlength, wline);
wline += wlength;
wlength = 0;
}
}
if (wlength > 0)
{
if (olength > 0)
oline[olength++] = ' ';
strncpy(&oline[olength], wline, wlength);
olength += wlength;
wline += wlength;
}
wline += strspn(wline, separators);
}
}
if (olength > 0)
printf("%.*s\n", olength, oline);
return 0;
}
在自己的源代码上运行时的输出:
#include <stdio.h> #include <string.h> /* */ /*
WordOfMoreThanSixtyCharacters--WithNaryASpaceInSight--ThoughThereIsPunctuation!
*/ enum { OUT_LENGTH = 60 }; int main(void) { char
oline[OUT_LENGTH]; // output line char iline[4096]; // input
line int olength = 0; // length of data in output line const
char separators[] = " \n\t"; while (fgets(iline,
sizeof(iline), stdin) != 0) { if (iline[0] == '.') continue;
int wlength; // word length char *wline = iline; // start of
word wline += strspn(wline, separators); while ((wlength =
strcspn(wline, separators)) > 0) { if (olength + 1 + wlength
> OUT_LENGTH) { printf("%.*s\n", olength, oline); olength =
0; if (wlength >= OUT_LENGTH) { printf("%.*s\n", wlength,
wline); wline += wlength; wlength = 0; } } if (wlength > 0)
{ if (olength > 0) oline[olength++] = ' ';
strncpy(&oline[olength], wline, wlength); olength +=
wlength; wline += wlength; } wline += strspn(wline,
separators); } } if (olength > 0) printf("%.*s\n", olength,
oline); return 0; }