掲示板利用宣言

 次のフォームをすべてチェックしてからご利用ください。

 私は

 題名と投稿者名は具体的に書きます。
 課題の丸投げはしません。
 ソースの添付は「HTML変換ツール」で字下げします。
 返信の引用は最小限にします。
 環境(OSとコンパイラ)や症状は具体的に詳しく書きます。
 返信の付いた投稿は削除しません。
 マルチポスト(多重投稿)はしません。

掲示板2

管理者用メニュー    ツリーに戻る    携帯用URL    ホームページ    ログ    タグ一覧

No.25562

is系関数とputs関数について
投稿者---あきき(2006/01/21 17:40:54)


以下の手順で操作したつもりですが、結果が予想に反するものです。

1 KBから入力。(仮に数字の”5”)
2 数字(文字列)を数値に変換する
3 1からの入力が
数字の時は、「数字」
数字以外のときは、「数字でない」
と表示するはずなんですが・・

5を入力しても、「数字でない」でと表示されて原因が分からなく、
puts()関数が原因なんでしょうか?

異常メッセージは、以下の通りです。
Stack around the variable 'str' was corrupted
// strのメモリーはどこかで破壊されているのでしょうか   
#include <stdio.h>
#include <ctype.h>

int main( void )
{
    int  ch;
    char str;

    scanf("%s%*c",&str);
    ch = (str - '0');// 数値変換していないのでしょうか?
    puts(isdigit(ch) ? "数字" : "数字でない");

    return 0;
}



この投稿にコメントする

削除パスワード

発言に関する情報 題名 投稿番号 投稿者名 投稿日時
<子記事> Re:is系関数とputs関数について 25565 とおり 2006/01/21 17:49:39
<子記事> Re:is系関数とputs関数について 25566 Blue 2006/01/21 17:50:22


No.25565

Re:is系関数とputs関数について
投稿者---とおり(2006/01/21 17:49:39)


>Stack around the variable 'str' was corrupted
>// strのメモリーはどこかで破壊されているのでしょうか 

のメッセージとは無関係に、まずはisdigit()が引数に何を取るか調べましょう。
"数字でない"と出力されたのなら、isdigit()の結果が予想と異なるのでしょう。
なぜ、その理由を考えずに、putsと関連づけて考えているのでしょうか…??


この投稿にコメントする

削除パスワード

No.25566

Re:is系関数とputs関数について
投稿者---Blue(2006/01/21 17:50:22)


is〜系のやつは、文字を判定するヤツです。

isdigit( 1 ) とすると 1 という文字コードが数字を表す文字かを判定します。

ASCIIコードである場合
48〜57の時 0以外がかえるようになっています。

ついでに
> scanf("%s%*c",&str);
%sは文字型配列に格納する時しかつかえません。

1文字ならば、普通に %c で読み込んでください。


この投稿にコメントする

削除パスワード

No.25568

Re:is系関数とputs関数について
投稿者---あきき(2006/01/21 18:11:13)


>is〜系のやつは、文字を判定するヤツです。
>
>isdigit( 1 ) とすると 1 という文字コードが数字を表す文字かを判定します。
>
>ASCIIコードである場合
>48〜57の時 0以外がかえるようになっています。
>

>ついでに
>> scanf("%s%*c",&str);
>%sは文字型配列に格納する時しかつかえません。
>
>1文字ならば、普通に %c で読み込んでください。

早速の返信ありがとうございます。
以下のように修正したら正常終了できました。
・is〜関数の勘違いを正してくれましてありがとうございます。

<修正ソース>
#include <stdio.h>
#include <ctype.h>

int main( void )
{
    char str;

    scanf("%c%*c",&str);
    puts(isdigit(str) ? "数字" : "数字でない");

    return 0;
}



この投稿にコメントする

削除パスワード

No.25591

Re:is系関数の引数について(引数の型)
投稿者---あきき(2006/01/22 00:30:46)


>>is〜系のやつは、文字を判定するヤツです。
>>
>>isdigit( 1 ) とすると 1 という文字コードが数字を表す文字かを判定します。
>>
>>ASCIIコードである場合
>>48〜57の時 0以外がかえるようになっています。
>
><修正ソース>
#include <stdio.h>
#include <ctype.h>

int main( void )
{
    char str;

    scanf("%c%*c",&str);
    puts(isdigit(str) ? "数字" : "数字でない");

    return 0;
}


BLUEさんのご指摘のもと、修正ソースで正常終了させることができました。ですが、isxxxx(int c)の関数の引数の型は、intでありcharでないので、int strに修正して、コンパイルした所、次のようなメッセージが出ました。

Expresion:(unsiged)(c+1) <= 256

エラーメッセージの意味が分からないのでなんともいえません。どなたかご教授ねがいます。そして、charからintにかえてなぜエラーになったのでしょうか。
isxxxx()関数の引数の型って、intですよね。
ちなみに、宣言時に、int、scanf()の変換子をcからdに変えた場合、
KBから、数字を入力すると、条件演算子は、偽判定。数字以外を入力すると異常終了してしまいます。考えれば考えるほど分からなくなります。


この投稿にコメントする

削除パスワード

No.25594

Re:is系関数の引数について(引数の型)
投稿者---nop(2006/01/22 00:46:07)


>BLUEさんのご指摘のもと、修正ソースで正常終了させることができました。ですが、isxxxx(int c)の関数の引数の型は、intでありcharでないので、int strに修正して、コンパイルした所、次のようなメッセージが出ました。
>Expresion:(unsiged)(c+1) <= 256
>エラーメッセージの意味が分からないのでなんともいえません。どなたかご教授ねがいます。そして、charからintにかえてなぜエラーになったのでしょうか。

環境が書いてないので推測ですが、リトルエンディアン環境での実行だからでしょう。
is〜()系の引数はint型ですが、0x00〜0xFFおよびEOF(多くの環境では-1)を想定しています。
「scanf("%c%*c",&str);」の文で、strがchar型の場合は0x00〜0xFFでしか有り得ませんが、
strがint型の場合、strは0x00、0x01000000〜0xFF000000(sizeof(int)==4を想定)となっているのです。

リトルエンディアン環境の時、何故、strに0x00、0x01000000〜0xFF000000が入るかというと、
scanf()の変換指示子が「%c」の為です。
「%c」はchar型オブジェクト領域へ入力文字を設定します。
つまり、strの先頭1バイトのみが書き変わるためです。
リトルエンディアン環境では、実アドレスの小さい方が上位バイトとなります。
つまり、scanf()では最上位バイトのみが書き変わるため、
0x00および0x01000000〜0xFF000000となるのです。

つまり、scanf()で指定するstrは、char型でなければなりません。
引数がint型であれば、キャストでint型にすればよいのです。



この投稿にコメントする

削除パスワード

管理者用メニュー    ツリーに戻る    携帯用URL    ホームページ    ログ    タグ一覧