0

行全体をチャンクとして印刷するのではなく、行の長さを使用して長い行を折り返し、(行の長さの) 1 行ずつ印刷しようとしています。行の長さごとに '\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ルーチンは元の入力にあった情報を削除します。次に、一度に 1 つのトークンを印刷するように呼び出します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 に答える