K&Rを読もう(12) 演習 1-19 文字列の逆順表示
今回はcopy関数の応用です。結構めんどい。
演習 1-19
文字列sを逆に並べよ。
ま、コピーの逆をすればいいな。と甘く考えていたけど、よく考えたら、C言語の文字列は、
012345\n\0
となるので、文字列の逆は、
543210\n\0
となる。
つまり、「改行をコピーしてはならない」という制限が付く。
その点を踏まえてコーディング。
#include <stdio.h> #include <stdlib.h> #define MAXLINE 1024 void reverse(char to[], char from[], int len); void copy(char to[], char from[]); int getline(char s[], int limit); int main(void) { int len; int max = 0; char line[MAXLINE]; char enil[MAXLINE]; int c; while ((len = getline(line, MAXLINE)) > 0) { if (len == MAXLINE - 1 && line[len - 1] != '\n') { while((c = getchar()) != EOF) { len++; if (c == '\n') break; } } reverse(enil, line, len); printf("%2d : %s", len,enil); if (len >= MAXLINE) printf("...\n"); } exit(EXIT_SUCCESS); } void reverse(char to[], char from[], int len) { int i; if (len > 0 && from[len - 1] == '\n') { /* 改行のチェック */ for (i = 0; i < len - 1; i++) to[len - 2 - i] = from[i]; to[len - 1] = '\n'; to[len] = '\0'; } else { copy(to, from); /* 改行が無い場合はコピーだけ */ } } void copy(char to[], char from[]) { int i; for (i = 0;(to[i] = from[i]) != '\0'; i++) ; }
- getlineは略。
- copyより1個引数を多くしてみた。strlen(3)でもいいと思う。
- シェルスクリプトのesacの真似て変数名はenilとした。lineの逆順。
- オーバーフローしたらコピーだけ。
実行結果
% ./ex-1-19 < ex-1-19.c | head 19 : >h.oidts< edulcni# 20 : >h.bildts< edulcni# 1 : 21 : 4201 ENILXAM enifed# 1 : 47 : ;)nel tni ,][morf rahc ,][ot rahc(esrever diov 35 : ;)][morf rahc ,][ot rahc(ypoc diov 35 : ;)timil tni ,][s rahc(enilteg tni 1 : 15 : )diov(niam tni
か、解読不能です。