課題
各入力行から、行の後ろのブランクやタブを取り除き、かつ空白行は全て削除するようなプログラムを書け。
回答
#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); char copy(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]; // 保存先 while ((len = getline(line1, MAX_LENGTH)) > 0) { if (copy(line2[num_line], line1) == TRUE) {; // 保存元から保存先へコピー num_line++; // 有効な行なら次の行へ } if (num_line >= MAX_LINE_NUM) { // 保存先の行数を使い切ったら終了 break; } } printf("\n --- copy --- \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; } /* 行コピーする */ char copy(char to[], char from[]) { u8 i; char flg = FALSE; i = 0; while ((to[i] = from[i]) != '\0') { if ((from[i] != ' ') && (from[i] != '\n') && (from[i] != '\t')) { flg = TRUE; } ++i; } return flg; }
実行内容
There we have none.
This is my uncle .
The only advice I can give is ...
実行結果
--- copy ---
There we have none.
This is my uncle .
The only advice I can give is ...
補足
「行の後ろのブランク」を、ピリオド以降のタブと空白と解釈した。