C言語の<ctype.h>のisspace()について教えてください。

まだ初心者なので、変な質問でしたらすみません。
ライブラリで用意されているisspace()関数があります。
空白類の文字判定を行えるとあり、引数はint型で指定することになっています。

そこで疑問なのですが文字列をgetcで取ってきた時にcはEOFの時にマイナスを取るわけですが、問題ないのでしょうか?

例えば
int c;
while( !isspace( c = getc( fp )) && c != EOF ){・・・

getcを(unsigned char)ででもキャストすると解消するとは思いますが、問題ないのならば加えたくありません・・。以上ですが、分かりにくい説明でご迷惑おかけします。
よろしくお願い致します。

このQ&Aに関連する最新のQ&A

A 回答 (3件)

> そこで疑問なのですが文字列をgetcで取ってきた時にcはEOFの時にマイナスを取るわけですが、


> 問題ないのでしょうか?

K&R 2 によると,
「各関数に対し,引数は int で与える。
 その値は EOF か,あるいは unsigned char として表現できるものでなければならず,
 戻り値は int となる。」
とありますから問題ないでしょう。(「各関数」というのは ctype.h で宣言された各関数のことです。)

心配なら先に EOF でないことをチェックしておけばいいです。
    • good
    • 0
この回答へのお礼

早急なご回答どうもありがとうございます。
すみません、yoppiiさんに言われた後調べたら載っていました。納得です!!

お礼日時:2003/09/26 18:44

こんにちは。

どこがわかりませんか?getc のプロトタイプ宣言は
int getc(FILE *stream)
ですから、ファイルストリームから読み込んだ
文字コードの値を int にキャストして戻してくれるわけです。
ですからキャストの必要はありません、というか EOF との比較ができなくなりますので
してはいけません。

また int は符号付き(signed)ですから、EOF(普通は -1)も楽に格納できます。
    • good
    • 0
この回答へのお礼

早急なご回答どうもありがとうございます。
すみません、主旨がわかりにくい質問ですよね・・。
isspace()の引数に-1を入れてもいいのかどうかが疑問でした。。。失礼しました^^;

お礼日時:2003/09/26 18:42

isspace()の引数が対象外の値の場合は0を返すことになっているようですので、問題は無いとは思いますが。



心配でしたら、以下のように書いてみてはどうでしょうか

int c;
while( (c=getc(fp)) != EOF && !isspace(c) )
{
.......

この場合、先に (c=getc(fp)) != EOF がFALSEになった段階で、次の !isspace(c) は評価されなくなります。
    • good
    • 0
この回答へのお礼

どうもありがとう御座います。
早急なお答え感謝です。

お礼日時:2003/09/26 18:33

このQ&Aに関連する人気のQ&A

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!

このQ&Aを見た人はこんなQ&Aも見ています

このQ&Aを見た人が検索しているワード

このQ&Aと関連する良く見られている質問

Qカッコ悪い使い方

カッコ悪い使い方ってあると思います。
モノの使い方、言葉の使い方、ファッション、
店の利用の仕方、あるいは、このサイトやネットの使い方etc
皆さんの考える「この使い方はカッコ悪い」を教えて下さい。

Aベストアンサー

ものの使い方ではないんですが、ひとつ挙げるとすれば、その人が外見的にカッコ良い人でもそうでなくても、いかにもカッコつけた態度をとっている人、つまり自意識過剰が見え見えの人はカッコ悪いと思います。

逆に言えば、自分に自信が持てるってことは、すごく幸せなことかも。
ま、それがその人の性格だったら、どうしようもないですけど・・・(-_-;)

Qchar型+char型ってint型? if(char型==int型)?

C言語の「汎整数拡張(インテグラルプロモーション)」というものに関するものだと思います。

char型とchar型を加えた結果は、char型でしょうか。それともint型でしょうか。
(下のプログラムの
printf("sizeof(a[0]+a[1])は%d\n", sizeof(a[0]+a[1])); /* char型+char型 */
という部分の結果は4なので、int型と考えるべきなのかな。)

私は、char型とint型の加算の結果はint型だと思っていましたが、
char型とchar型の加算の結果はやはりchar型だと思っていました。
(それが間違えているのでしょうか。)


if(a[0]==i) /* char型とint型の比較(?) */
の部分では、左辺はchar型、右辺はint型ですが、このように型の違う変数を比較しても文法上構わないのでしょうか。
(私は、「比較は必ず型の同じもの同士でしかできない」と思っていました。)
左辺はchar型のように見えて、じつはint型ですか。


#include <stdio.h>
int main(void)
{
char a[4];
int i=77;
printf("sizeof(int)は%d\n", sizeof(int));
printf("sizeof(char)は%d\n", sizeof(char));
printf("sizeof('M')は%d\n", sizeof('M'));
printf("sizeof(a[0])は%d\n", sizeof(a[0]));

a[0]='M';
a[1]=7+6;
a[2]=a[0]+a[1];
printf("sizeof(a[0]+a[1])は%d\n", sizeof(a[0]+a[1])); /* char型+char型 */
printf("sizeof(+a[0])=%d\n", sizeof(+a[0]));

if(a[0]==i) /* char型とint型の比較(?) */
puts("a[0]==i");
else
puts("a[0]!=i");

return(0);
}

ちなみにワーニングもエラーもなんにもでません。

C言語の「汎整数拡張(インテグラルプロモーション)」というものに関するものだと思います。

char型とchar型を加えた結果は、char型でしょうか。それともint型でしょうか。
(下のプログラムの
printf("sizeof(a[0]+a[1])は%d\n", sizeof(a[0]+a[1])); /* char型+char型 */
という部分の結果は4なので、int型と考えるべきなのかな。)

私は、char型とint型の加算の結果はint型だと思っていましたが、
char型とchar型の加算の結果はやはりchar型だと思っていました。
(それが間違えているのでしょう...続きを読む

Aベストアンサー

「sizeof 単項式」について補足です。

これは sizeof 演算子が「単項演算子」であるために書かれたものだと思われます。
例えば同様に単項演算子である ++ も、「++ 単項式」です。

では単項式とは何なのかというと、これは以下のようなものを指します。(抜けがあるかもしれませんが。)
・定数
・名前(変数名や関数名など)
・( 式 )
・後置式

( 式 ) はおなじみの「式の結果を返す」ものですが、実はこれ全体で単項式です。
本来「sizeof 単項式」では ( ) を必要としないので、sizeof より優先順位の低い演算子を含む式を裸で渡すことはませんが、( ) で囲めばどんな式でも書けるわけです。

後置式は「配列構文によるアドレス参照式」や「関数呼び出し式」、「メンバ参照式」「後置型インクリメント/デクリメント式」です。
なので、
> sizeof(a[0])
> と書いたら、[ ] という演算子は2項演算子だから、a[0]は単項式になっていない
は、わざわざ ( ) で囲まず sizeof a[0] と書いても、正しい単項式なので問題ありません。
(これらの演算子は、全て sizeof より優先順位が上になっています。)

先に ++ も単項式を取る、ということを書きましたが、++ だって
  ++*(p + n)
のような記述が通るのだから、sizeof でも問題がなくて当然です。

また、例えば ++ では「オペランドは左辺値でなければならない」という原則があり、左辺値でない式に ++ を適用するとコンパイルエラーが発生します。
しかし、sizeof に「オペランドはオブジェクトでなければならない」などという原則を聞いたことがありません。
無論コンパイルエラーも起きませんし、期待通りに式の値のサイズが返ります。
「式の値のサイズ」というのはコンパイル時に判明しているものなので、取得できて当然といえば当然ですが、これがCで定められた仕様かどうかというのは残念ながら見つけることはできませんでした。
ただし、質問にあるような sizeof の文法は全て正しく、警告が出ないのは仕様通りだというのは間違いありません。

「sizeof 単項式」について補足です。

これは sizeof 演算子が「単項演算子」であるために書かれたものだと思われます。
例えば同様に単項演算子である ++ も、「++ 単項式」です。

では単項式とは何なのかというと、これは以下のようなものを指します。(抜けがあるかもしれませんが。)
・定数
・名前(変数名や関数名など)
・( 式 )
・後置式

( 式 ) はおなじみの「式の結果を返す」ものですが、実はこれ全体で単項式です。
本来「sizeof 単項式」では ( ) を必要としないので、sizeof より優...続きを読む

Qラブホテルで、本来以外の使い方をした経験、ありますか?

本来の使い方は、皆さん知っていますね?
そうではなくて、本来以外の使い方です。
テレビで「ラブホ女子会」が流行っている話をしていましたが、例えばそういうこととか、単に寝るために泊まったとか、出張で使ったとか、カラオケとか、昼寝とか・・・とにかく、本来の使い方ではない使い方です。
もちろんその後も、本来の使い方はしないでチェックアウトしたという前提です。

ラブホテルによっては、そういう使い方を認めないところもあるようですが、本来以外の使い方をした経験はありますか?

Aベストアンサー

お盆に家族旅行に行ったとき高速で30Km渋滞と表示されていたので、雄琴温泉に仕方なく宿泊しようとした。何処も満室で仕方なくラブホに家族で宿泊した。
回転するベッドや明るさの調整できる風呂があり、子供が大はしゃぎで遊んでいた。
妻とこんな使い方もあるなーと話をした。家族全員だと雄琴なら6,7万円必要なところ8000円ですみ
朝食もディナーのような肉料理だった。フロントの人は、普通はこんな使い方しないけど、いい勉強になった
こんな使い方も考えてみたいと言っていた。

Qchar c = 'a'; char h[1] = c; エラー

char型のものを char[]型に代入したいです。

char c = 'a';
char h[1] = c;

として、

h[0] は \x97
h[1] は \x00

にしたいです。
型変換の方法を教えてください。

Aベストアンサー

とりあえず、確認を。

C では、'a'の表す値は 0x61 = 97 であって、 \x97 ではないと思います。
(\xnnn を、十六進数の意味に取りましたが、あってますでしょうか?
この場合、C では通常 0xnnn のように書くと思います。)
ので、 これは 0x61 のことをおっしゃっていると仮定します。

> char h[1] = c;
っと、これではたぶんコンパイルが通りません。

char h[1] = {c};

のように、配列であることを明示して代入してください。
この式では、前半でh という名前の、*長さ1 の* char の配列変数を確保します。
後半で、その中を初期化しています。
添え字は 0 からはじまるので、この場合、h[0] に c の内容が代入されます。
1個しか場所を確保していないので、 h[1] の位置のデータは内容が不定です。
文字列として h を扱いたいのであれば、 C の文字列には終端として 0 が必要ですから、
char c = 'a';
char h[2] = { c, '\0'};

のような書き方が必要になります。
これで、お望みのデータになると思います。

とりあえず、確認を。

C では、'a'の表す値は 0x61 = 97 であって、 \x97 ではないと思います。
(\xnnn を、十六進数の意味に取りましたが、あってますでしょうか?
この場合、C では通常 0xnnn のように書くと思います。)
ので、 これは 0x61 のことをおっしゃっていると仮定します。

> char h[1] = c;
っと、これではたぶんコンパイルが通りません。

char h[1] = {c};

のように、配列であることを明示して代入してください。
この式では、前半でh という名前の、*長さ1 の* char の配列変数...続きを読む

Qこのお箸の使い方ってOKなんですか?はたして疑問

たまに目にする箸の使い方。
フォークとナイフのように右と左に1本づつ持って
何かを切る、という箸の使い方って正しいんでしょうか。
私個人的にはそういう使い方を目にすると
嫌悪感を覚えるのですが。以前テレビを見ていたとき
君島十和子さんが堂々とそういう使い方をするのを
見て驚きました。ネットで調べたけれど、この使い方に
ついては見つけることができませんでした。
どなたか教えてください。

Aベストアンサー

調べてきました。
「ちぎり箸」というそうで、間違った使い方のひとつとのことです。

参考URL:http://www.table-manners.org/dainty_kaiseki/chopsticks/

Qunsigned int型と int型の型変換の上位性

if(-10<1u)の条件判定はunsigned型で評価され偽となります。
int型 unsigned int型とも32ビットで考えたとき、
1u = 0x00000001 -10 = 0xfffffff6で10進法では4294967286になります。
条件判定をunsigned型で考えれば確かに-10<1uは偽になり
int型で考えれば-10<1uは真になります。
「通常の算術変換」によれば、「一方のオペランドがunsigned int型をもつ時、他のオペランドをunsigned int型に型変換するとあります。」
よって、if(-10<1u)の条件判定はunsigned型で評価され偽となりますが、
「一方のオペランドがint型をもつ時、他のオペランドをint型に型変換する。」では何故いけないのでしょうか?
宜しく願います。

Aベストアンサー

> <符号無し整数型から符号付き整数型に変換する際、元の値が表現できなければ、>
> とは、具体的にどのような場合をいうのでしょうか?

例えば、

unsigned int a = UINT_MAX;
int b = (int)a;

とした場合、aの値はUINT_MAXであり、int型の表現範囲に収まりません。
具体的には、int型が32ビットで負値を2の補数で表現する処理系であれば、int型の表現範囲は-2147483648~+2147483647になりますから、UINT_MAXの値(4294967295)を表現することができません。

> <処理系定義の値になるか処理系定義のシグナルが発生します。>

int型の負値の表現方法は、2の補数以外に、1の補数や符号ビット+絶対値が考えられます。これらの場合にUINT_MAXをint型にキャストするとどんな値になるか考えてみてください。
処理系定義のシグナルというのは、例えばオーバーフロー例外(プロセッサがハード的に発生させる割り込みのようなものと考えてください)が発生して、結果として何らかのシグナルハンドラが呼び出されるかもしれないことを意味しています(シグナルハンドラについてはsignal関数を調べてください)。

> <符号無し整数型から符号付き整数型に変換する際、元の値が表現できなければ、>
> とは、具体的にどのような場合をいうのでしょうか?

例えば、

unsigned int a = UINT_MAX;
int b = (int)a;

とした場合、aの値はUINT_MAXであり、int型の表現範囲に収まりません。
具体的には、int型が32ビットで負値を2の補数で表現する処理系であれば、int型の表現範囲は-2147483648~+2147483647になりますから、UINT_MAXの値(4294967295)を表現することができません。

> <処理系定義の値になるか処理系定義...続きを読む

Q日本語 「よう」の使い方

「よう」の使い方で同じ使い方のものを選ぶ問題の中で、
 1. 彼の家は大きくて、お城のようです。と
 2. 彼は日本人のように上手に話せます。が、同じ「よう」の使い方になっていました。1.は名詞+のようだ。 2.は名詞+のように+名詞or形容詞の使い方だと私は思うのですが......。1.と2.が同じ使い方になるのはどうしてなのでしょうか........?教えてください。

Aベストアンサー

コメントにお答えします。

まず、最初のご質問文の中にある誤りを指摘していませんでしたが、
 2.は名詞+のように+名詞or形容詞
は誤りで、
 2.は名詞+のように+動詞or形容詞or形容動詞
とすべきです。


では、本題。

>>>1.と2.の「よう」の意味は同じ、使い方は同じではないということですか??????。

問題は、解答者に対してこの2つの比較を求めています。
1「~のようです」(「ようです」の終止形)
2「~のように」(「ようだ」の連用形)

あなたの考え方は、
 1.は名詞+の+「ようだ/ようです(=終止形)」。
 2.は名詞+の+「ように(=連用形)」+動詞or形容詞or形容動詞
となっているから、使い方は異なるのではないか、ということですよね。

しかし、
国語(日本語)の問題で「同じ使い方のものを選べ」という問題がある場合、
単に活用形が異なるだけの言葉同士を「使い方が違う言葉」として扱うことは、通常ありません。


「お城のようだ/ように/ようです」「日本人のようだ/ように/ようです」は、
A + の + ようだ/ようです = 「Aのようだ/です」
の形です。
つまり、「形として、使い方が同じ」です。

そして、どちらも
・「Aではないけれども、Aに似ている」
・「Aではないけれども、Aの感じがする」
という意味になります。
つまり、「意味として、使い方が同じ」です。

ですから、1と2は、「形としても、意味としても、使い方は同じ」ということになります。


では!

コメントにお答えします。

まず、最初のご質問文の中にある誤りを指摘していませんでしたが、
 2.は名詞+のように+名詞or形容詞
は誤りで、
 2.は名詞+のように+動詞or形容詞or形容動詞
とすべきです。


では、本題。

>>>1.と2.の「よう」の意味は同じ、使い方は同じではないということですか??????。

問題は、解答者に対してこの2つの比較を求めています。
1「~のようです」(「ようです」の終止形)
2「~のように」(「ようだ」の連用形)

あなたの考え方は、
 1....続きを読む

Qint main(int argc, char* argv[]) についての質問

こんにちは.つね日ごろ思っている質問させてください.
Cの参考書には,
(1)
void main(void)
{
}

(2)
int main(int argc, char* argv[])
{
return 0;
}
の2つのパターンが記載されていますが,
どういう違いがあるのでしょうか?

(1)の場合main関数は,型を持たず,引数も持たない.
※Turbo Cなどのコンパイラーでは,
return文がないと警告出ます.
(2)の場合は,int 型をかえし,引数はint型 変数と char型ポインタ配列(?)
を指定している.
といったくらいしか分かりません.

(2)に関してもう少し述べれば,
コマンドラインからファイルを指定し,実行することが
できると勉強した記憶があるのですが,
理解があいまいです.

特に(2)の場合のmain関数の意味と,その使い方について
アドバイスお願い致します.

Aベストアンサー

> (1)
> void main(void)
  ...
> (2)
> int main(int argc, char* argv[])
  ...
> の2つのパターンが記載されていますが,どういう違いがあるのでしょうか?

(1) は、間違いです。少なくとも ANSI-C の規格に合致していません。

main() は、特別な関数で、ANSI-C の規格では以下の三通りのうちのどれか
でなくてはいけない、と定められています。

int main(void)
int main(int argc, char *argv[]);
int main(int argc, char *argv[], char *envp[]);

因みに三番目の形式では、三つ目の引数には環境変数が入ります。
以下のようなコードで確認ができます。

int main(int argc, char *argv[], char *envp[])
{
  int i = 0;
  while (envp[i]) {
    printf("envp[%d] = '%s'\n", i, envp[i]);
    ++i;
  }
  return 0;
}


> ※Turbo Cなどのコンパイラーでは,return文がないと警告出ます

Turbo C は、規格に厳格なのでしょう。返り値が void なのはおかしいので、
int だとみなすよ、という警告も出てるはず。で、int が帰り値だとみなし
ているので return が無いと、返り値が不定になるよ、と警告を出している
のでしょう。

> (1)
> void main(void)
  ...
> (2)
> int main(int argc, char* argv[])
  ...
> の2つのパターンが記載されていますが,どういう違いがあるのでしょうか?

(1) は、間違いです。少なくとも ANSI-C の規格に合致していません。

main() は、特別な関数で、ANSI-C の規格では以下の三通りのうちのどれか
でなくてはいけない、と定められています。

int main(void)
int main(int argc, char *argv[]);
int main(int argc, char *argv[], char *envp[]);

因みに三番目の形式では、三...続きを読む

Qタイガーバームの使い方

おみやげでタイガーバームを頂きました。使い方を教えて下さい。
基本的な使い方から意外な使い方まで、何でもお願いします。

Aベストアンサー

「何にでも効く」というふれ込みの万能?軟膏ですね。(笑)香港やシンガポールにはこれで大金持ちになった方が作った「タイガーバームガーデン」なるものがありました。
基本的には筋肉痛や肩こりなどに効くとされていますが、匂いがものすごいため、人前に出るときにはどうかと思います。
使用法は、少量をとり、肌に良くすりこみます。さらにマッサージをするすと、有効成分が浸透しやすく、いっそう効果的だそうです。
でも、けして切り傷や生傷には使用しないで下さい。 また体の粘膜部分など敏感なところへの使用もだめですよ。


人気Q&Aランキング