バイナリ形式出入力について(初心者です)

フォーラム(掲示板)ルール
フォーラム(掲示板)ルールはこちら  ※コードを貼り付ける場合は [code][/code] で囲って下さい。詳しくはこちら
スーパーコック

バイナリ形式出入力について(初心者です)

#1

投稿記事 by スーパーコック » 11年前

学校で出された課題でどうしてもうまく作れないプログラムがあります。
課題の内容は、
test3.txt
satoh
8
181
193
80
176
185
132
124
89

上記の形式のテキストファイルの内容を、バイナリファイルに書き込むプログラムを作成せよ。ただし、
1, 2 行目はテキストとして書き込み、行末には改行文字を書き込む
3 行目以降は、点数 1 つあたり 1 バイトの整数値としてバイナリ形式で書き込む
さらに書き込んだバイナリファイルから内容を読み取り、出力するプログラムを作成せよ。
というものです。

一つ目のプログラムは、
#include <stdio.h>
#define NUM 64

int main(void){
FILE*fp;
FILE*fp2;

fp = fopen("test3.txt","r");
if(fp == NULL){
printf("ファイルをオープンできませんでした。\n");
return 1;
}

fp2 = fopen("test3.bin","wb");
if(fp2 == NULL){
printf("ファイルをオープンできませんでした。\n");
return 1;
}

char name[NUM];
int classes;
int score[NUM];
int i;

fgets(name,NUM,fp);
fscanf(fp,"%d",&classes);
for(i=0; i<classes; i++){
fscanf(fp,"%d",&score);
}


fprintf(fp2,"%s",name);
fprintf(fp2,"%d\n",classes);
fwrite(score,sizeof(int),classes,fp2);


fclose(fp);
fclose(fp2);

return 0;
}

二つ目のプログラムは
#include <stdio.h>
#define NUM 64

int main(void){
FILE*fp;

fp = fopen("test3.bin","rb");
if(fp == NULL){
printf("ファイルをオープンできませんでした。\n");
return 1;
}

char name[NUM];
int classes;
char score[NUM];
int i;

fgets(name,NUM,fp);
fscanf(fp,"%d",&classes);
fread(score,sizeof(char),classes,fp);


printf("%s",name);
printf("%d\n",classes);
for(i=0; i<classes; i++){
printf("%d\n",(int)score);
}

fclose(fp);

return 0;
}

としましたが、3行目以降の整数が全く違う整数になってしまいます。
どこが間違っているのでしょうか。
ちなみに私はまだ習って一年にも満たないプログラミング初心者です。

Poco
記事: 161
登録日時: 14年前

Re: バイナリ形式出入力について(初心者です)

#2

投稿記事 by Poco » 11年前

バイナリファイルの読み書きはfread()、fwrite()だけでやってください。
テキストデータもfread()、fwrite()で。

アバター
みけCAT
記事: 6734
登録日時: 14年前
住所: 千葉県
連絡を取る:

Re: バイナリ形式出入力について(初心者です)

#3

投稿記事 by みけCAT » 11年前

コードを提示するときは、BBcodeを有効にした状態でcodeタグで囲み、
かつきちんとインデントをしていただけると、見やすくて助かります。
複雑な問題?マシンの性能を上げてOpenMPで殴ればいい!(死亡フラグ)

アバター
みけCAT
記事: 6734
登録日時: 14年前
住所: 千葉県
連絡を取る:

Re: バイナリ形式出入力について(初心者です)

#4

投稿記事 by みけCAT » 11年前

スーパーコック さんが書きました:1, 2 行目はテキストとして書き込み、行末には改行文字を書き込む
この条件が満たされていないようです。
1つめのプログラムの

コード:

fprintf(fp2,"%s",name);
という行を、

コード:

fprintf(fp2,"%s\n",name);
としてみてください。[/s]
【修正】fgetsで読み込んだデータに改行文字が付いているので、それが引き継がれ、それっぽく動作するようです。
スーパーコック さんが書きました:3行目以降の整数が全く違う整数になってしまいます。
1、2行目は正常なのですか?
【修正】上記の理由により大丈夫そうです。
Poco さんが書きました:バイナリファイルの読み書きはfread()、fwrite()だけでやってください。
テキストデータもfread()、fwrite()で。
今回の場合、そんな縛りプレイをする必要はないと思います。
そもそも「テキストファイル」もバイナリファイルの一種です。
確かに読み込みにfscanfを利用するのはまずいかもしれませんが、fgetcは用いてよいと思います。
書き込みにfprintfを利用するのは全く問題ないと思います。
最後に編集したユーザー みけCAT on 2013年11月17日(日) 14:14 [ 編集 1 回目 ]
複雑な問題?マシンの性能を上げてOpenMPで殴ればいい!(死亡フラグ)

アバター
みけCAT
記事: 6734
登録日時: 14年前
住所: 千葉県
連絡を取る:

Re: バイナリ形式出入力について(初心者です)

#5

投稿記事 by みけCAT » 11年前

スーパーコック さんが書きました:3 行目以降は、点数 1 つあたり 1 バイトの整数値としてバイナリ形式で書き込む
この条件が、ほとんどの環境で満たされていないと思います。
LSI C-86 試食版でさえ、int型は2バイトです。
使用しているコンパイラを教えてください。
複雑な問題?マシンの性能を上げてOpenMPで殴ればいい!(死亡フラグ)

アバター
へろりくしょん
記事: 92
登録日時: 14年前
住所: 福岡

Re: バイナリ形式出入力について(初心者です)

#6

投稿記事 by へろりくしょん » 11年前

みけCAT さんが書きました:
スーパーコック さんが書きました:3 行目以降は、点数 1 つあたり 1 バイトの整数値としてバイナリ形式で書き込む
この条件が、ほとんどの環境で満たされていないと思います。
LSI C-86 試食版でさえ、int型は2バイトです。
使用しているコンパイラを教えてください。
コードは見づらすぎてさっぱり見てませんが。

unsigned char 型でいいのでは? 一般に1バイトで整数型です。

スーパーコック

Re: バイナリ形式出入力について(初心者です)

#7

投稿記事 by スーパーコック » 11年前

返信ありがとうございます。
失礼しました、コードは以下のとおりです。

コード:

[*]#include <stdio.h>
#define NUM 64

int main(void){
FILE*fp;
FILE*fp2;

fp = fopen("test3.txt","r");
if(fp == NULL){
printf("ファイルをオープンできませんでした。\n");
return 1;
}

fp2 = fopen("test3.bin","wb");
if(fp2 == NULL){
printf("ファイルをオープンできませんでした。\n");
return 1;
}

char name[NUM];
int classes;
int score[NUM];
int i;

fgets(name,NUM,fp);
fscanf(fp,"%d",&classes);
for(i=0; i<classes; i++){
 fscanf(fp,"%d",&score[i]);
}


fprintf(fp2,"%s",name);
fprintf(fp2,"%d\n",classes);
fwrite(score,sizeof(int),classes,fp2);


fclose(fp);
fclose(fp2);

return 0;
}

コード:

 #include <stdio.h>
#define NUM 64

int main(void){
FILE*fp;

fp = fopen("test3.bin","rb");
if(fp == NULL){
printf("ファイルをオープンできませんでした。\n");
return 1;
}

char name[NUM];
int classes;
char score[NUM];
int i;

fgets(name,NUM,fp);
fscanf(fp,"%d",&classes);
fread(score,sizeof(char),classes,fp);


printf("%s",name);
printf("%d\n",classes);
for(i=0; i<classes; i++){
 printf("%d\n",(int)score[i]);
}

fclose(fp);

return 0;
} 
となります。コンパイラはlinuxの端末を利用しています。

スーパーコック

Re: バイナリ形式出入力について(初心者です)

#8

投稿記事 by スーパーコック » 11年前

unsigned char型にしたところ、無事表示されました。
いろいろとお手数をおかけましたが、ありがとうございました。

閉鎖

“C言語何でも質問掲示板” へ戻る