課題
文字列Sを逆に並べる関数reverse(s)を書け。さらに、この関数を使って、入力を一時に1行ずつ逆転するプログラムを書け。
回答
#include <stdio.h> #include <limits.h> #include <string.h> #define MAX_LINE_NUM 1000 /* 入力行数の最大値 */ #define MAX_LENGTH 1000 /* 入力文字列長の最大値 */ const int MIN_COPY_LENGTH = 80; /* コピーする最低文字列長 */ const char TRUE = 1; const char FALSE = 0; typedef unsigned long long u8; int getline(char line[], u8 maxline); void copy(char to[], char from[]); void reverse(char to[], char from[]); /* 行を逆順にコピーする */ /** * @fn Main * @brief * @param * @return * @detail */ int main(void) { u8 i, len, num_line = 0; // 行数 char line1[MAX_LENGTH]; // 保存元(読み取った文字列) char line2[MAX_LINE_NUM][MAX_LENGTH]; // 保存先 char flg = TRUE; while ((len = getline(line1, MAX_LENGTH)) > 0) { if (flg == TRUE) { copy(line2[num_line], line1); // 通常コピー flg = FALSE; } else { reverse(line2[num_line], line1); // 逆順コピー flg = TRUE; } num_line++; // 有効な行なら次の行へ if (num_line >= MAX_LINE_NUM) { // 保存先の行数を使い切ったら終了 break; } } printf("\n --- result --- \n"); // タイトル for (i = 0; i < num_line; i++) { // 保存した行数だけ printf("%s", line2[i]); // 保存先から取り出して印字 } return 0; } /* getline: sに行を入れる */ int getline(char s[], u8 lim) { int c; u8 i; char flg = FALSE; for (i = 0; (i < lim - 1) && ((c = getchar()) != EOF) && (c != '\n'); ++i) { if (c == '.') { // コロンを発見したら flg = TRUE; // 発見フラグをONする } if ((flg == FALSE) || // コロン発見前または (c != ' ') || // スペースではない、または (c != '\t')) { // タブでもなければ s[i] = c; // コピーする } } if (c == '\n') { s[i] = c; ++i; } s[i] = '\0'; return i; } /* 行を逆順にコピーする */ void reverse(char to[], char from[]) { u8 i = 0, len = strlen(from) - 1; // 改行の直前まで while (1) { to[i] = from[len - i - 1]; if (i == (len - 1)) { to[i + 1] = '\n'; to[i + 1] = '\0'; break; } i++; } } /* 行コピーする */ void copy(char to[], char from[]) { int i = 0; while ((to[i] = from[i]) != '\0') { ++i; } }
実行内容
This is a pen.
This is not a pen.
実行結果
--- result ---
This is a pen.
.nep a ton si sihT