gpt4 book ai didi

C编程的(K&R 1-22)折叠输入问题

转载 作者:行者123 更新时间:2023-12-03 21:41:41 25 4
gpt4 key购买 nike

我是一名 Delphi、Ruby 和 Javascript 程序员,终于开始学习 C - 从 K&R 开始。我正在尽最大努力不要跳到前面去使用尚未介绍的库和概念。由于这是教程的第一章,我只坚持使用一些语言功能,并希望保持这种状态。

1-22 不熟悉:

Write a program to ``fold'' long input lines into two or more shorter lines after the last non-blank character that occurs before the n-th column of input.

Make sure your program does something intelligent with very long lines, and if there are no blanks or tabs before the specified column.

我在没有寻求外部帮助的情况下达到了 1-22,但我一直在努力解决 1-22 的“大部分”工作版本。我认为我的算法..erm..选择很糟糕。

到目前为止,我已经决定将输入折叠到 40 个字符。使用整数除法(/和模数 %),我计算出每行需要折叠多少次,跳转到该列并向后计数,直到遇到空格。空格被替换为“\n”。重复 +40 个字符。

如果没有遇到空格,我们将在每个列停止处进行硬折叠。

我发现有些线偷偷越过了我的边界,想知道我是否不应该这样做将输入读入 char line[],然后一次将 40 个字符复制到缓冲区,折叠缓冲区,然后将缓冲区复制回 line[]..但这似乎是一项繁重的工作,尤其是在没有 string 的情况下。 h

代码在下面,我正在寻找正确方向的提示与解决方案,因为我认为我快到了。

#include <stdio.h>

#define MAXBUF 1000
#define WRAP 20

int getline(char s[],int lim);

int main(void)
{
int len; /* length of each input */
int folds; /* how many folds we've performed */
int lines; /* lines the input breaks down to given len */
int index; /* index of fold */
int didfold; /* true (1) if we were able to fold on a ' ' */
int i; /* loop counter */
char line[MAXBUF+1]; /* input line */
char buf[MAXBUF+1]; /* temp buffer for copying */

while ((len=getline(line,MAXBUF)) > 0)
{
/* how many times should we fold the input
account for left overs
*/
lines = len / WRAP;
if (len % WRAP != 0)
++lines;
/* init */
folds = 1;

while (lines>0)
{
didfold = 0;
for (index=(WRAP*folds)-1;index>0 && !didfold;--index)
{
if (line[index] == ' ')
{
line[index] = '\n';
didfold = 1;
--lines;
++folds;
}
}
// if (!didfold)
// {
// i = 0;
// while ((buf[i] = line[i]) != '\0');
// ++i;
// for(index=i=0;buf[i]!='\0';++index,++i)
// {
// line[index] = buf[i];
// if (index==(WRAP*folds))
// {
// ++i;
// line[i] = '\n';
// didfold = 1;
// ++folds;
// linelength -= WRAP * folds;
// }
// }
// }

}
printf("--------------------|||||\n");
printf("%s",line);
}
return 0;
}


int getline(char s[],int lim)
{
int i,c;

for (i=0;i<=lim && ((c = getchar()) != EOF) && c != '\n'; ++i)
s[i] = c;
if (c == '\n') {
s[i] = '\n';
++i;
}
s[i] = '\0';

return i;
}

我有另一个版本将自身索引到 column - 40 并向前计数更多问题。

更新

以下是我正在解决的错误,所以我远未完成,但是..

我的方向是否正确?我想确保我掌握了经典UNIX 文本过滤器。到目前为止,这段代码感觉好多了,但仍然很糟糕——我只是不喜欢感觉我掌握了一个关键概念,但需要用漂亮的代码来完成它..

/* Exercise 1-22. Write a program to ``fold'' long input lines into two or more shorter
lines after the last non-blank character that occurs before the n-th column of input.

Make sure your program does something intelligent with very long lines, and if there
are no blanks or tabs before the specified column. */

#include <stdio.h>

#define WRAP 20

int main(void)
{
char buf[WRAP+1];
int bufpos = 0;
int last_whitespace = -1;

for(bufpos=0;bufpos<(WRAP-1);++bufpos) {
putchar('-');
}
putchar('|');
putchar('\n');
bufpos=0;

while ((buf[bufpos]=getchar())!=EOF) {
// if at buffer or newline
if (bufpos==(WRAP-1) || buf[bufpos] == '\n' || buf[bufpos] == '\t') {
++bufpos;
buf[bufpos] = '\0';

if (buf[bufpos]==' ' || buf[bufpos] == '\n') {
// whitespace, flush buf and go.
printf("%s",buf);
} else {
if (last_whitespace>0) {
buf[last_whitespace] = '\n';
printf("%s",buf);
} else {
//hard fold!
printf("%s",buf);
putchar('\n');
}
}
for (bufpos=0;bufpos<WRAP;++bufpos)
buf[bufpos] = '\0';
bufpos=0;
last_whitespace=-1;
} else {
if (buf[bufpos]==' ')
last_whitespace = bufpos;
++bufpos;
}
}
return 0;
}

最佳答案

逐个字符地通读每一行,并维护一些指针(或者,如果您还没有使用指针,则保留偏移量)。一个用于“行的开头”,它将从指向行的开头开始,一个用于您看到的最后一个空格,它将从 NULL 开始(如果您使用的是偏移量,则 -1 会代替),一个用于当前阅读位置。

然后,每当遇到一些空白时,您应该检查是否可以输出从前一个空白到(但不包括)当前空白的所有内容,而不会超出 WRAP 字符。如果可以,那就马上输出,更新之前的空白指针指向当前的空白。如果不能,则输出一个换行符而不是之前的空格,并更新行首指针和最后一个空格指针。

现在唯一剩下的就是“处理非常长的行”,你可以通过查看行的开头和看到的最后一个空格是否都在同一个地方来做到这一点,但我们仍然 超出了 WRAP 列 — 这意味着我们有一个词无法放在一行中。在那种情况下,我们可能应该在这里插入一个换行符,重置行首,然后继续。

确保在到达输入行的末尾时还打印任何尚未打印的内容,并输出最后的换行符。

这个算法的好处是它实际上不需要一组行来工作——因为它是逐个字符地处理的,所以它可以在一次读取输入文件一个字符的情况下进行很小的更改,给定至少包含 WRAP 个字符的缓冲区。

关于C编程的(K&R 1-22)折叠输入问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5228209/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com