はじめての C

C programming note*1
行単位の 入出力が 可能になったので、次は メニューカードのように それぞれの行を 中央揃えにする プログラムを つくっていきます。
それから、エディタ画面に print したときに 中央揃えに なることと、フォントの幅が 全て 同じだと 仮定しておきます。
その部分の コードが、

#include 

void center(char buf[], int w)
{
int off;
int n;
int i;

n = strlen(buf) - 1; /* -1 for '\n' */

if (w < n)
return;
off = (w - n + 1) / 2;

for (i = n + 1; i >= 0; i--)
buf[i + off] = buf[i];

while (off--)
buf[off] = ' ';
}

n が 入力した 1行の長さ、w が print 画面の 最大幅に なります。

strlen() という 関数が 新しく 使われている。

これは、引数で 与えられた 文字列の 文字数を 返す (末尾の ナル文字は 数えない)。

文字列を 扱うときには、とても よく使う 標準ライブラリ関数だ。

fgets() のところでも 述べたように、配列の名前を 添字なしで 書くと 「その配列の 先頭の要素への アドレス」 の意味に なるので、ここでは そのことを 利用して、buf という 配列の 先頭アドレスを (引数として) 渡している。(p132)

off は 最大幅から 入力した 文字列の長さを 引き、半分にしたものです。 これを 文字列の前に 空白として 当てはめていきます。
文字列の 後ろは、改行 '\n' で 次の行に 飛ぶので、今回は コードで 考える必要は ありません。
方法としては、まず 入力した もとの 格納領域 buf[] を、1文字ずつ ずらしながら、off分だけ 拡張します。

for (i = n + 1; i >= 0; i--)
buf[i + off] = buf[i];
当然、格納領域 buf[0] から buf[off] までの 配列は 不要になります。
この空いた配列に buf[off] から 順に 空白コードの ' ' を 入れていきます。
while (off--)
buf[off] = ' ';
以上の 操作は、実際には 入力と 出力の間で 行ないますから、先に つくった 関数 carte() にも 変更が 加えられます。
#define MAX_SIZE (80 + 1 + 1)
#define WIDTH 80 /* width of editor screen */

void carte(FILE *fp)
{
char buf[MAX_SIZE];

while (fgets(buf, MAX_SIZE, fp) != NULL) {
center(buf, WIDTH);
fputs(buf, stdout);
}
}

*1:「作ってわかる Cプログラミング」