開発環境
- OS X Lion - Apple(OS)
- Emacs、BBEdit - Bare Bones Software, Inc. (Text Editor)
- プログラミング言語: C
- Clang (コンパイラ)
プログラミング言語C 第2版 ANSI規格準拠 (B.W. カーニハン D.M. リッチー (著)、 石田 晴久 (翻訳)、共立出版)の第1章(やさしい入門)、1.10(外部変数と通用範囲)の演習 1-23、1-24を解いてみる。
その他参考書籍
- プログラミング言語Cアンサー・ブック 第2版 (クロビス・L.トンド、スコット・E.ギンペル(著)、矢吹 道郎(翻訳))
演習 1-23.
コード
sample.c
#include <stdio.h>
void remove_comment(int c);
void comment();
void quote(int c);
/* コードからコメントを削除 */
int main()
{
int c;
while ((c = getchar()) != EOF) {
remove_comment(c);
}
printf("/* \"これはコメントではない\" */\n");
putchar('/');
putchar('*');
putchar('*');
putchar('/');
putchar('\n');
return 0;
}
/* ただの文字列かコメントかを判断しながら
* コメントを見つける
*/
void remove_comment(int c)
{
int d;
if (c == '/')
if ((d = getchar()) == '*')
comment();
else if (d == '/') {
putchar('/');
remove_comment(d);
} else {
putchar('/');
putchar(d);
}
else if (c == '"' || c == '\'') {
putchar(c);
quote(c);
}
else
putchar(c);
}
/* コメントの終わりを見つけてコメントを削除 */
void comment()
{
int c, d;
c = getchar();
d = getchar();
while(c != '*' || d != '/') {
c = d;
d = getchar();
}
}
/* コメントではない文字列を削除するのを防ぐ */
void quote(int c)
{
int d;
while ((d = getchar()) != c) {
putchar(d);
if (d == '\\') {
d = getchar();
putchar(d);
}
}
}
入出力結果(Terminal)
$ cat sample.c | ./a.out
#include <stdio.h>
void remove_comment(int c);
void comment();
void quote(int c);
int main()
{
int c;
while ((c = getchar()) != EOF) {
remove_comment(c);
}
printf("/* \"これはコメントではない\" */\n);
putchar('/);
putchar('*);
putchar('*);
putchar('/);
putchar('\n);
return 0;
}
void remove_comment(int c)
{
int d;
if (c == '/)
if ((d = getchar()) == '*)
comment();
else if (d == '/) {
putchar('/);
remove_comment(d);
} else {
putchar('/);
putchar(d);
}
else if (c == '" || c == '\') {
putchar(c);
quote(c);
}
else
putchar(c);
}
void comment()
{
int c, d;
c = getchar();
d = getchar();
while(c != '* || d != '/) {
c = d;
d = getchar();
}
}
void quote(int c)
{
int d;
while ((d = getchar()) != c) {
putchar(d);
if (d == '\\) {
d = getchar();
putchar(d);
}
}
}
/* "これはコメントではない" */
/**/
$
演習 1-24.
コード
sample.c
#include <stdio.h>
int parentheses, brackets, braces; /* () [] {} */
void find_error(int c);
void skip_comment();
void quote(int c);
int main()
{
int c;
extern int parentheses, brackets, braces;
while ((c = getchar()) != EOF) {
if (c == '/')
if((c = getchar()) == '*')
skip_comment();
else
find_error(c);
else if (c == '"' || c == '\'')
quote(c);
else
find_error(c);
if (parentheses < 0) {
printf("エラー「(」\n");
parentheses = 0;
}
if (brackets < 0) {
printf("エラー「[」\n");
brackets = 0;
}
if (braces < 0) {
printf("エラー「{」\n");
braces = 0;
}
}
if (parentheses > 0)
printf("エラー「)」\n");
if (brackets > 0)
printf("エラー「]」\n");
if (braces > 0)
printf("エラー「}」\n");
return 0;
}
/* 釣り合いがとれてない括弧を探す */
void find_error(int c)
{
extern int parentheses, brackets, braces;
if (c == '(')
++parentheses;
else if (c == '[')
++brackets;
else if (c == '{')
++braces;
else if (c == ')')
--parentheses;
else if (c == ']')
--brackets;
else if (c == '}')
--braces;
}
/* コメント内の括弧は無視するためにコメントは探さない
* ([[ }
*/
void skip_comment()
{
int c, d;
c = getchar();
d = getchar();
while(c != '*' || d != '/') {
c = d;
d = getchar();
}
}
/* シングルクォートやダブルクォートで囲まれた括弧は無視 */
void quote(int c)
{
int d;
while ((d = getchar()) != c) {
if (d == '\\')
getchar();
}
}
入出力結果(Terminal)
$ cat sample.c|./a.out
$ cat tmp.c
#include <stdio.h>
int main()
{
printf("(");
putchar('(');
printf("]");
putchar(']');
/* { */
printf(}]];
return 0;
}
$ cat tmp.c|./a.out
エラー「[」
エラー「[」
エラー「{」
エラー「)」
$
0 コメント:
コメントを投稿