プログラミング1
Report#6
提出日 : 2003年 7月 3 日 (木)
所 属 : 工学部情報工学科1年次
学籍番号 : 035750C
氏 名 : 又吉 威瑠
<1> 課題
コマンドラインから受け取った文字列の大文字と小文字を変換するプログラムを作成せよ。入力は1バイトの表示文字とし、アルファベット文字以外は変換しない。
<2> プログラムと実行結果
1) プログラム
[nw0350:~/prog1] j03050% cat report#6-1.c
/*
Program : report#6.c
Student-ID : 035057C
Author : MATAYOSHI,Takeru
Data : 030701
*/
#include <stdio.h>
#include <ctype.h> --------------------------------------------------[1]
void replace(char *dest, char *str); --------------------------------[2]
main(int argc, char **argv)
{
for(argv++; *argv != NULL; argv++){ --------------------------------[3]
printf("%s=>", *argv);
replace(*argv, *argv); ----------------------------------------[4]
printf("\n");
}
}
void replace(char *dest, char *str) --------------------------------[5]
{
for(str; *str != NULL; str++, dest++){
if(islower(*str)){
*dest = toupper(*str);
printf("%c", *dest);
}
else if(isupper(*str)){
*dest = tolower(*str);
printf("%c", *dest);
}
else
printf("%c", *str);
}
}
2) 実行結果
[Takeru-MATAYOSHI:~/prog1] j03050% gcc report#6-1.c
[Takeru-MATAYOSHI:~/prog1] j03050% ./a.out This is report#6-1.c
This=>tHIS
is=>IS
-1-
[Takeru-MATAYOSHI:~/prog1] j03050% ./a.out Xsea#21
Xsea#21=>xSEA#21
<3> 考察
1)プログラムの解説
[1]プリプロセッサ命令で、ファイルctype.hを取り込む
[2]使用関数を宣言「voidでreplace(char *dest, char *str)」
[3]初期値argc++(arg+1)を*argvがNULLと等しくなるまでargvを1ずつ増加させていきな ながら、{}で挟まれたプログラムを繰り返す。
[4]replace(*argv, *argv);は、
void replace(char *dest, char *str)
{
for(str; *str != NULL; str++, dest++){
if(islower(*str)){
*dest = toupper(*str);
printf("%c", *dest);
}
else if(isupper(*str)){
*dest = tolower(*str);
printf("%c", *dest);
}
else
printf("%c", *str);
}
}
を示してる。
[5]replaceという名の関数で、関数を呼び出した側から関数に渡す文字型*destと*strを 宣言する。
2)コマンドライン引数
まず、コマンドラインとは何かを知らないという重病だったのでしらべてみました。
調べてわかったこと
main関数にも引数を渡すことができる。この main関数に渡す引数のことを「コマンドライン引数」という。
main関数へ渡せる引数は、
1.引数の総個数
2.引数の文字列を示すポインタの配列
の 2つである。
一般に
int main(int argc, char *argv[]) と記述し、
int argc: 引数の総個数(プログラム名も含む)
char *argv[]: 引数の文字列を示すポインタの配列を表す。
3)ctype.h
標準ライブラリ関数を使うには、ctype.h をインクルードする必要がある。
-2-
使った標準ライブラリ関数
tolower() 文字c が大文字なら、小文字に変換した値を返す。 大文字以外なら、そのままの値を返す。
toupper() 文字c が小文字なら、大文字に変換した値を返す。 小文字以外なら、そのままの値を返す。
4)main関数に値を返すという意味不明なものがでてきた。
例
#include <stdio.h>
int main(int argc,char *argv[])
{
int i;
printf("引数の総個数 = %d\n", argc);
for (i = 0; i < argc; i++) {
printf("%d番目の引数 = %s\n", i, argv[i]);
}
}
プログラムの名称をprog.cとする。引数としてABC DEF GHI を指定することとし、ABC DEF GHI とコマンドラインから入力する。
結果
引数の総個数 = 4
0番目の引数 = A:\SMPL.EXE
1番目の引数 = ABC
2番目の引数 = DEF
3番目の引数 = GHI
つまり、main(int argc, char*argv[])に引数が渡ったことを表す。
argv[0]
|
prog.cのアドレス
|
argv[1]
|
ABCのアドレス
|
argv[2]
|
DEFのアドレス
|
argv[3]
|
GHIのアドレス
|
こんな感じで渡ったのであろう。
5)初めに出来たプログラム
#include <stdio.h>
void replace(char *dest, char *str);
main(int argc,char **argv)
{
for(argv++; *argv !=NULL; argv++){
printf("#befor=> %s\n",*argv);
replace(*argv, *argv);
-3-
printf("#after=> %s\n",*argv);
}
}
void replace(char *dest, char *str)
{
for(str; *str !=NULL; str++, dest++){
if('A'<=*str && *str<='Z')
*dest=*str+'a'-'A';
else if('a'<=*str && *str<='z')
*dest=*str-'a'+'A';
else
*dest=*str;
}
}
実行結果
[nw0350:~/prog1] j03050% gcc report#6.c
[nw0350:~/prog1] j03050% ./a.out This is a report#6
#befor=> This
#after=> tHIS
#befor=> is
#after=> IS
#befor=> a
#after=> A
#befor=> report#6
#after=> REPORT#6
[nw0350:~/prog1] j03050% ./a.out aZgh#$%12
#befor=> aZgh#0
#after=> AzGH#0
これはislowerなどを使わずに作ったものです。なんか暗号化あたりで似たようなものをした覚えがあるが気のせいだよね・・・。
if('A'<=*str && *str<='Z')
*dest=*str+'a'-'A';
else if('a'<=*str && *str<='z')
*dest=*str-'a'+'A';
else
*dest=*str;
この部分を標準ライブラリ関数使って書き換え、他の部分を改良して課題のプログラムができた。どっちが良いプログラムがわからないけど・・・。
<4> 反省と感想
今回の課題はプログラム自体が短いので(この前のが長過ぎたのか?)精神的にすこし楽だった気がする。しかし、みんなが早く終わって帰ってしまったので聞きたいことが聞けなかった。吸収できなかったのが残念だ。みんな余裕だったのかな?自分的にはやはりきつかったけど・・・。あと、運が良ければ課題二つで前期のノルマが終わるので気を引き締めていきたい。追試にはならないようにしたいね~。
-4-
<5> 参考文献とURL
c実践プログラミング Steve Oualline 著
望月 康司 監訳
谷口 功 訳
発行所 オライリー・ジャパン
c言語スタートブック 高田 美樹 著
発行所 技術評論社
初心者のためのポイント学習C言語
http://www9.plala.or.jp/sgwr-t/
-5-