自动换行程序C

3
在《C语言程序设计语言》第一章的结尾处,有一些练习需要完成。我现在正在做的一个练习要求你编写一个程序,将长字符串文本包装成多行,每行长度固定。下面的函数完美地实现了这个功能,除了最后一行无论指定行宽为多少都不会被包装成多行之外。
// wrap: take a long input line and wrap it into multiple lines
void wrap(char s[], const int wrapline)
{
    int i, k, wraploc, lastwrap;

    lastwrap = 0; // saves character index after most recent line wrap
    wraploc = 0; // used to find the location for next word wrap

    for (i = 0; s[i] != '\0'; ++i, ++wraploc) {

        if (wraploc >= wrapline) {
            for (k = i; k > 0; --k) {
                // make sure word wrap doesn't overflow past maximum length
                if (k - lastwrap <= wrapline && s[k] == ' ') {
                    s[k] = '\n';
                    lastwrap = k+1;
                    break;
                }
            }
            wraploc = 0;
        }

    } // end main loop

    for (i = 0; i < wrapline; ++i) printf(" ");
    printf("|\n");
    printf("%s\n", s);
}

我发现问题出在变量wraploc上,它会一直递增,直到大于wrapline(行的最大索引)。一旦它大于wrapline,就会在适当的位置插入一个换行符,并将wraploc重置为0。
问题在于,在最后一行中,即使应该大于wraplinewraploc也永远不会大于wrapline。它在字符串迭代期间完美地递增,直到最后一行。以这个例子为例:
char s[] = "This is a sample string the last line will surely overflow";
wrap(s, 15);

$ ./a.out
               |
this is a
sample string
the last line
will surely overflow

这条线代表应该换行的位置。在这种情况下,wraploc 的值为14,但实际上字符数明显多于此。

我不知道为什么会出现这种情况,有人能帮帮我吗?

(另外,我是 C 语言的完全初学者,对指针没有任何经验,请在回答中避免使用指针,谢谢)。


尝试使用 for(k = i - 1; k > 0; --k) 而不是 for(k = i; k > 0; --k) - ciphermagi
不,没有影响 @ciphermagi - samrap
我无法理解 k - lastwrap <= wrapline 的用途。这个条件检查真的必要吗? - Kushagr Jaiswal
此外,程序对于 if (wraploc == wrapline) 的情况也能正常工作,而不仅仅是 if (wraploc >= wrapline) - Kushagr Jaiswal
2个回答

3
你需要将iwraploc相加,直到达到wrapline(在此示例中为15)时,进行换行操作。 当你换行时,你需要从i回溯,找到上一个空格字符的位置。 这意味着在下一行中,lastwrap 位置和 i 之间已经有一些字符存在,也就是说你不能在那里将wraploc重置为0。 尝试使用 wraploc = i-lastwrap 进行设置。

1
非常感谢!我简直不敢相信我没有意识到那个事实。 - samrap

3
如果有人和我一样遇到了源字符串中换行的问题,那么这里是我的答案:

inline int wordlen(const char * str){
   int tempindex=0;
   while(str[tempindex]!=' ' && str[tempindex]!=0 && str[tempindex]!='\n'){
      ++tempindex;
   }
   return(tempindex);
}
void wrap(char * s, const int wrapline){

   int index=0;
   int curlinelen = 0;
   while(s[index] != '\0'){

      if(s[index] == '\n'){
         curlinelen=0;
      }
      else if(s[index] == ' '){

         if(curlinelen+wordlen(&s[index+1]) >= wrapline){
            s[index] = '\n';
            curlinelen = 0;
         }

      }

      curlinelen++;
      index++;
   }

}


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接