0

我正在尝试使用行长来换行并一次打印一行(行长),而不是将整行打印为一个块。我认为在每行长度添加 '\n' 字符就可以完成这项工作并编写了以下代码。

void wrap(char *tok, int len)
{
  int i, h;
  char *ss = tok;
  for (h = linelen; h < (len + 1); (h + linelen))
    {
      ss[h] = '\n';
      printf("%d\n", h);
      h += linelen;
    }
  char *token = strtok(ss, "\n");
  while (token)
    {
        printf("%s\n", token);
        token = strtok(NULL, "\n");
    }
}

但是这段代码似乎不起作用。我还有哪些其他方法可以实现换行?

4

3 回答 3

2

从这篇文章中被盗:是否可以只打印出 C 字符串的某个部分,而不制作单独的子字符串?

#include <stdio.h>
#include <string.h>

int main(void) {

    char *str = "helo world";
    int total_len = strlen(str);
    int single_len = 3;
    for (int i = 0; i < total_len; i += single_len) {
        /* print at most first three characters (safe) */
        printf("%.*s\n", single_len, str + i);
    }

    return 0;
}
于 2013-04-06T16:14:47.067 回答
1

您不需要更改原始字符串,只需要在必要时打印出额外的换行符:

void wrap(char *str, int len, int linelen) {
    int i;
    for (i = 0; i < len; ++i) {
        printf("%c", str[i]);
        if (i > 0 && i % linelen == 0) {
            printf("\n");
        }
    }
}

如果您的原始字符串中可能包含换行符,您可以跟踪当前行的长度,以便正确换行下一行:

void wrap(char *str, int len, int linelen) {
    int i, currlen;
    for (i = 0, currlen = 0; i < len; ++i, ++currlen) {
        printf("%c", str[i]);
        if (str[i] == '\n') {
            currlen = 0;
        }
        if (currlen > 0 && currlen % linelen == 0) {
            printf("\n");
        }
    }
}
于 2013-04-06T16:13:28.397 回答
1

您的程序似乎想要分解tok成多个linelen字节,但您似乎并不关心要替换什么字符来实现这一点。这会使您的wrap例行程序丢弃原始输入中的信息。然后您调用strtok一次打印一个令牌,但损坏已经造成。

相反,我相信你应该重组你的代码,以便strtok用于查找令牌,然后计算打印当前令牌是否会让你超过你linelen。如果是这样,您打印一个换行符,打印令牌,并计算您当前运行的行长度,就像您刚刚打印的令牌的长度一样。您在同一行上打印的每个标记都会增加运行行的长度。

void wrap(char *tok, int linelen)
{
  int len = 0;
  char *ss = tok;
  char *token = strtok(ss, " \t\n");
  while (token) {
    int tokenlen = strlen(token);
    if (len && (len + tokenlen + 1 > linelen)) {
      puts("");
      len = 0;
    }
    if (tokenlen) {
      printf("%s%s", len ? " " : "", token);
      len += 1 + tokenlen;
    }
    token = strtok(0, " \t\n");
  }
  if (len) puts("");
}

您的原始实现没有考虑如何处理制表符。如果将所有线性空白字符添加到strtok定界符,则所有制表符都将被视为标记分隔符,并且在包装输入时将被删除。正确处理制表符会使您的运行行长度计算复杂化,因为制表符会导致行长度跳转到下一个制表位。

于 2013-04-06T16:19:49.010 回答