ページ 11

c言語のコマンドライン引数を使った文字の判別のプログラム

Posted: 2012年1月31日(火) 13:19
by jun
c言語のコマンドライン引数を使った文字の判別のプログラムです。自分で書いたプログラムではセグメンテーション違反になってしまいます。どこがおかしいでしょうか?下に正しい実行例をのせておきます。

<code>
#include <stdio.h>
#include<ctype.h>

char *isalpha_p(void) {
return "an alphabet";
}
char *isdigit_p(void) {
return "a digit";
}
char *islower_p(void) {
return "lowercase";
}
char *isupper_p(void) {
return "uppercase";
}

int main(int argc, char *argv[])
{
int (*p[])(int c) = {isalpha, isdigit, islower, isupper};
char *(*q[])(void)={isalpha_p, isdigit_p, islower_p, isupper_p};


if (argc < 3)
{
printf("Usage: ./5-1b -adlu char\n");
}

int i;
char c;

c = argv[2];

if(argv[1]="-a"){
i=0;
}else if(argv[1]="-d"){
i=1;
}else if(argv[1]="-l"){
i=2;
}else if(argv[1]="-u"){
i=3;
}else{
printf("Error: unknonw option: \"%c\"\n", c);
printf("Usage: ./5-1b -adlu char\n");
}


if(p(c)) {
printf(" '%s' is %s.\n", c, q());
}else{
printf(" '%s' is NOT %s.\n", c, q());
}
return 0;
}

実行例$ ./check_char ←※プログラム名を check_char として、コマンドライン引数なしで実行
Usage: ./check_char -adlu char

$ ./check_char -a 0
'0' is NOT an alphabet.

$ ./check_char -a U
'U' is an alphabet.

$ ./check_char -e 3 ←※謎のオプション "-e" を指定
Error: unknonw option: "-e".
Usage: ./check_char -adlu char

$

Re: c言語のコマンドライン引数を使った文字の判別のプログラム

Posted: 2012年1月31日(火) 13:40
by 沖 滉均
codeタグの使い方が正しくありません。
プレビューで確認してから書き込みしてくださいね。

で、これはCであってC++ではないんですね?
Cだと途中で変数の宣言はできないはずですのでコンパイルも通らないと思うのですが

コード:

	if(argv[1]="-a"){
		i=0;
	}else if(argv[1]="-d"){
		i=1;
	}else if(argv[1]="-l"){
		i=2;
	}else if(argv[1]="-u"){
		i=3;
	}else{
		printf("Error: unknonw option: \"%c\"\n", c);
		printf("Usage: ./5-1b -adlu char\n");
	}
それとは別に引数判定をしている箇所のif文の条件が全て代入文になっています
条件判定は = ではなく == です。
また、想定外のオプション引数を入力した場合にエラー出力だけして終了していないためiが不定値になります。

セグメンテーション違反はこちらでは発生しなかったんですがおそらく
c = argv[2];
の部分ではないでしょうか?
ちょっとうろ覚えですが、argv[2]はchar*型ですからchar型には入れられない(…はず)です。

Re: c言語のコマンドライン引数を使った文字の判別のプログラム

Posted: 2012年1月31日(火) 13:50
by たかぎ
沖 滉均 さんが書きました:Cだと途中で変数の宣言はできないはずですのでコンパイルも通らないと思うのですが
そんなことはありません。
沖 滉均 さんが書きました:ちょっとうろ覚えですが、argv[2]はchar*型ですからchar型には入れられない(…はず)です。
代入可能です。

Re: c言語のコマンドライン引数を使った文字の判別のプログラム

Posted: 2012年1月31日(火) 14:03
by 沖 滉均
そうなんですか…やはりうろ覚えで答えるものではありませんね。
申し訳ありませんでした…
私の書き込みは全て忘れてください

Re: c言語のコマンドライン引数を使った文字の判別のプログラム

Posted: 2012年1月31日(火) 14:12
by beatle
C言語は確かに最新版では変数の定義場所はどこでも良くなっていますね.

c = argv[2];
に関しては,確かにコンパイルは通るかもしれませんが,意味的にはおかしい代入ですから,やってはいけない処理ですね.
コンパイラの立場からすればエラーではないが,意味を考えればエラーだということですね.
(セグメンテーション違反の原因にはならないはずです)

どういうコマンドライン引数を渡したらセグメンテーション違反になるのかの説明が欲しいところです.

Re: c言語のコマンドライン引数を使った文字の判別のプログラム

Posted: 2012年1月31日(火) 14:17
by non
たかぎ さんが書きました:
沖 滉均 さんが書きました:Cだと途中で変数の宣言はできないはずですのでコンパイルも通らないと思うのですが
そんなことはありません。
沖 滉均 さんが書きました:ちょっとうろ覚えですが、argv[2]はchar*型ですからchar型には入れられない(…はず)です。
代入可能です。
前者はC99の場合は、ということでしょうが、後者はどういう意味でしょうか?

編集:だぶりましたか。

Re: c言語のコマンドライン引数を使った文字の判別のプログラム

Posted: 2012年1月31日(火) 14:35
by たかぎ
non さんが書きました:
たかぎ さんが書きました:
沖 滉均 さんが書きました:Cだと途中で変数の宣言はできないはずですのでコンパイルも通らないと思うのですが
そんなことはありません。
沖 滉均 さんが書きました:ちょっとうろ覚えですが、argv[2]はchar*型ですからchar型には入れられない(…はず)です。
代入可能です。
前者はC99の場合は、ということでしょうが、後者はどういう意味でしょうか?
前者については、C99以降ですので、現行規格のC11でも可能ですね。
後者についてですが、ポインタ型の値は整数型に暗黙的に型変換されますので、代入可能です。
セマンティックスが正しいかどうかは文脈次第です。

Re: c言語のコマンドライン引数を使った文字の判別のプログラム

Posted: 2012年1月31日(火) 14:41
by 沖 滉均
あと、もう1点だけ最後に…
途中引数の数の判定等エラー処理が一応入っていますが、argc == 1だろうがreturnしてないので
c = argv[2]やif(argv[1] == "-a")などとしているところが原因になったりはしないでしょうか?
引数が不足していた場合など

Re: c言語のコマンドライン引数を使った文字の判別のプログラム

Posted: 2012年1月31日(火) 14:45
by non
たかぎさん
了解です。

本題ですが、
char と char*の区別がされてません。
あっちこっちに間違いがあります。
例えば、文字列の比較には strcmpを使います。