ページ 11

C言語におけるファイル操作

Posted: 2010年4月26日(月) 23:12
by やっくん
コンパイラ:VC2008

以下のC言語ソースコードでファイル(下記参照)から値を読み込む場合、int型で読み込む場合はエラーを吐かないんですが、unsigned char型にしたらファイルクローズする際にエラーが起こります。
どうしてでしょうか?
#include <stdio.h>

int main(void)
{
          int i;               // roop用
    char buff[256];      // buffer
    int a[10];           // ファイルの値格納先
    unsigned char b[10]; // ファイルの値格納先
    FILE *fp;

    fp = fopen("t.txt", "r");
    for(i = 0; i < 10; i++){
        fgets(buff, 256, fp);
        sscanf(buff, "%d", &b);
        printf("%d\n", b); //
    }
    fclose(fp);// 値格納先がunsigned char型の場合、ここでエラー
    return 0;
}


<t.txt>
0
1
2
3
4
5
6
7
8
9
画像

Re:C言語におけるファイル操作

Posted: 2010年4月26日(月) 23:43
by なっきー
sscanf(buff, "%d", &b);
printf("%d\n", b);

int型なら%dでもいいですが、
unsigned char型は%cを使わなければならないのでは・・・

Re:C言語におけるファイル操作

Posted: 2010年4月27日(火) 00:17
by やっくん
返信ありがとうございます。
>unsigned char型は%cを使わなければならないのでは・・・
仰るとおりです(^^;
今まで%dは整数値を指定するものだからchar型で整数値を扱う場合にも使えるんじゃないかと思っておりました。
上のソースコードでも
sscanf(buff, "%d", &b);
printf("%d\n", b);
この部分は予期通りに普通に動いてしまいます。
エラーが出ているのがファイルクローズ時なのですが、どのような動作でエラーになっているかわかりますでしょうか?

また、unsigned char型にファイルから整数値を読み込みたいのですがどのようにすれば良いでしょうか?
0~255の画素値を持つ画像を処理する場合などはint型では無駄にメモリを取ってしまうことになるので。 画像

Re:C言語におけるファイル操作

Posted: 2010年4月27日(火) 00:26
by たかぎ
> int型なら%dでもいいですが、
> unsigned char型は%cを使わなければならないのでは・・・

%dと%cでは、型の大きさだけではなく、まったく意味が異なります。
本来であれば%hhdとすべきなのですが、VC++はサポートしていませんので、いったん%dを指定してintの変数で受けるか、文字列として取得して、変換するしかありません。

Re:C言語におけるファイル操作

Posted: 2010年4月27日(火) 08:23
by やっくん
>たかぎさん
返信ありがとうございます。
途中、一度int型で受けてunsigned char型に変換すると後がスムーズに行きました。
出力する場合は整数型なので%dとして出力しましたが、%cにしてみるとビープ音やら不明な文字が出ました。
char型,unsigned char型はコンパイラで文字、または整数値の適切なものに勝手に識別してくれるようですね。

しかし、char型は1バイトのメモリを確保するのでsigned型なら-128~127、unsigned型なら0~255の数値を扱える訳ですがコンパイラではどのように文字か整数値かを識別してるのでしょうか?0~255までフルにビットを使ったらその判定をする場所ができないようにも思えます。

Re:C言語におけるファイル操作

Posted: 2010年4月27日(火) 13:02
by やっくん
自分で調べてみて自己解決しました。
scanfなどのようなものは%dだとint型のバイト数分を読み込み、printfなどの%dは整数型で表示する。
だから、unsigned char型をscanfでは%d指定できないが、printfなどでは%dが使える。
と判断しました。
文字と数字の識別も理解できました。

なっきーさん、たかぎさんありがとうございました。 画像

Re:C言語におけるファイル操作

Posted: 2010年4月27日(火) 13:08
by やっくん
解決とさせていただきます。

Re:C言語におけるファイル操作

Posted: 2010年4月27日(火) 13:41
by たいちう
> char 型,unsigned char型はコンパイラで文字、
> または整数値の適切なものに勝手に識別してくれるようですね。
> ...(略)
> コンパイラではどのように文字か整数値かを識別してるのでしょうか?
> 0~255までフルにビットを使ったらその判定をする場所ができないようにも思えます。

そのような識別はされていませんよ。
もしかすると、数字が出力されたから適切な整数値に変換される、と考えたのでしょうか?

文字コード0x41(10進数で65)を指定すると文字'A'が出力されるのと同様に、
文字コード0x31(10進数で49)を指定すると文字'1'が出力されます。

↑このような事を言っているんじゃないやい、という場合は、
具体的に説明してください。

Re:C言語におけるファイル操作

Posted: 2010年4月27日(火) 17:25
by やっくん
たいちうさん、返信ありがとうございます。

自分の勘違いなんですが、
char型は整数値と文字両方を扱えるってことなので、char型に整数値か文字どちらが入っているかわかる情報が無ければおかしい!!と思っていたんです。

よくよく考えれば、

>文字コード0x41(10進数で65)を指定すると文字'A'が出力される
このように文字'A'は文字コード0x41(10進数65)に対応しています。
これをCのソースにするとにすると、
char moji = 'A';
printf("%c", moji); // 出力は A
printf("%d", moji); // 出力は 65
こうなりますよね。
これがどうしてこうなるのかが良く理解できてませんでした。
今はようやく整理できました(^^;