プロが教えるわが家の防犯対策術!

ファイルの取り扱いについて、どのように記述すればいいのかが分かりません。
分からないことが多いので(1)~(4)の質問に分けています、Cの勉強は趣味程度にしかできていないので、詳しくご回答いただけると嬉しいです。
自分なりに書いてみます、間違いがあればご指摘宜しくお願いします。

(1)Aを頭文字にして100個のcsvファイルを作成 (a1,a2…a100)

char A[100]
FILE *fp;
for(i=1;i<101;i++)
{
snprintf(A,sizeof A,"A%d.csv",i);
if((fp = fopen(A,"w"))!=NULL) {exit(1);}
}

(2)A1を開きデータを入れる、この動作を同様に2~100で繰り返す。

A1に入れたいデータはx,y,zで1000行
fp = fopen("A1.csv","a");
for(z=1;z<11;z++)
{
for(y=1;y<11;y++)
{
for(x=1;x<11;x++)
{
fprintf(fp,"%d,%d,%d\n",x,y,z);
}
}
}
fclose(fp);

これでこんな感じに書き込まれるはず・・・
1,1,1
2,1,1
3,1,1
 ・
 ・
 ・
10,10,10

これを同様に2~100のファイルに対して一気に行いたいですが、書き方が分かりません。

(3)再びA1を開きx=10,Y=10の時のzの値を知りたい。
こんな事はできるのでしょうか? もし無理なら~行目のデータを呼び出す

(4)そしてA1を開きx=10,Y=10の時の、zだけを上書き。

長くなってすいません、分からない事だらけなので宜しくお願いします。

A 回答 (6件)

#5 です。

 回答プログラムだけで字数制限いっぱいになってしまいました。

あなたの質問は「ランダムアクセスの仕方を教えてください。」というものです。
http://ja.wikipedia.org/wiki/%E3%83%A9%E3%83%B3% …
ファイルは、1個作成しようが100個作成しようがやっていることは同じですから、N_FILES の値を好みに応じて変更してください。
プログラムの要点は
 #define FORM "%4d,%4d,%4d,%10d\n"
 #define FORM_SIZE 26 //一行当たり
と出力形式を改行\nを含めて 26バイトに固定していることです。それによって任意 x,y,z点の値nを参照したり、変更したりできるようになっています。

とりあえず、あなたの希望に答えて、その都度ファイルをオープンするプログラムを
 Database sample:
  1. Create
  2. Input
  3. Show
  4. Correct
 Input number
の表示順(1~4)に入力し、実行してみてください。
各作業毎にホルダー内のCSVファイルを確認すれば、どのような処理がなされているかわかると思います。


その他参照URL
http://www9.plala.or.jp/sgwr-t/c/sec17.html
http://www1.cts.ne.jp/~clab/hsample/File/File06/ …
    • good
    • 0
この回答へのお礼

ご回答ありがとうございます、返事を書くのがすごく遅くなってしまいました。
こう言った操作が有った事を知らなかったので、大変勉強になりました。
本当にありがとうございました。

お礼日時:2010/11/22 09:06

#include <stdio.h>


#include <stdlib.h> //exit()
#define N_FILES 1
#define X_MAX 3
#define Y_MAX 3
#define Z_MAX 3
#define FORM "%4d,%4d,%4d,%10d\n"
#define FORM_SIZE 26 //一行当たり
void _create(void);
void _input(void);
void _show(void);
void _correct(void);
FILE *open_file(char*,char*);

int main(void)
{
int cmd;
printf("Sample Database:\n");
printf("\t1. Create\n");
printf("\t2. Input\n");
printf("\t3. Show\n");
printf("\t4. Correct\n");
printf("Select one ");
scanf("%d", &cmd);
switch (cmd) {
case 1:
_create();
break;
case 2:
_input();
break;
case 3:
_show();
break;
case 4:
_correct();
break;
default:
printf("Try again.\n");
break;
}
return 0;
}


void _create(void)
{
char file_name[32];
int i;
FILE *fp;
for(i=0;i<N_FILES;i++){
sprintf(file_name,"A%d.csv",i);
if((fp=fopen(file_name,"w"))==NULL){
printf("Can't open %s file.\n", file_name);
exit(1);
}
}
fclose(fp);
}


void _input(void)
{
int x,y,z,n=0;
FILE *fp;
fp=open_file("file name? ", "w+");
for(z=0;z<Z_MAX;z++){
for(y=0;y<Y_MAX;y++){
for(x=0;x<X_MAX;x++){
fprintf(fp,FORM,x,y,z,n++);
}
}
}
fclose(fp);
}


void _show(void)
{
int x,y,z,n,offset;
FILE *fp;
fp=open_file("file name? ","r");
printf("code x,y,z? ");
scanf("%d,%d,%d",&x,&y,&z);
offset=x + Y_MAX*y + X_MAX*Y_MAX*z;
fseek(fp,FORM_SIZE*offset,SEEK_SET);
fscanf(fp,"%d,%d,%d,%d", &x,&y,&z,&n);
printf("dat(%d,%d,%d)= %d\n",x,y,z,n);
fclose(fp);
}


void _correct(void)
{
int x,y,z,n,offset,value;
FILE *fp;
fp=open_file("file name? ","r+");
printf("code x,y,z? ");
scanf("%d,%d,%d",&x,&y,&z);
offset=x+Y_MAX*y+X_MAX*Y_MAX*z;
fseek(fp,FORM_SIZE*offset,SEEK_SET);
fscanf(fp,"%d,%d,%d,%d", &x,&y,&z,&n);
printf("data(%d,%d,%d)= %d ? ",x,y,z,n);
scanf("%d", &value);
fseek(fp,FORM_SIZE*offset+15,SEEK_SET);
fprintf(fp,"%10d\n",value);
fclose(fp);
}


FILE *open_file(char *comment, char *mode)
{
char file_name[32];
FILE *fp;
printf("%s",comment);
scanf("%s",file_name);
if((fp=fopen(file_name,mode))==NULL){
printf("Can't open %s file.\n", file_name);
ext(1);
}
return fp;
}
    • good
    • 0

もとの質問の本筋から大きく外れてしまうが、以下は一般的な話です。



たいていの人は fclose の戻り値の確認を忘れがちですが、fclose の戻り値を必ず確認
すべきです。なぜなら、ファイルへの書き込み処理で実はエラーがあった、ということ
が、ファイルのクローズ時に検出されるということは、ありえるからです。

つまり、ファイルクローズ時に何らかの異常が検出される可能性があるため、それをアプリ
側で補足できる必要があります。
    • good
    • 0

ファイルを作成するまでの方法については、他の方の指摘通りですが、


ファイル出力というのは、挿入処理をすることはではないので
出力する桁数がかわってしまうと内容が壊れてしまいます。
なので、(4)の仕様を実現するために、
出力(fprintf)の時にフォーマットを指定しましょう。("%2d,%2d,%2d\n"とか)
#テキストエディタを上書きモートで編集するつもりになれば感覚はつかめると思います。

# 以下、出力したファイルの内容はソートされていることが前提になりますけれど。。。
(3)については、上記の対応で1行のサイズが固定になるので
行数*(Nバイト+改行)の位置にfseekすればジャンプ(fseek)することは
できるようになります。

ですがまぁ、取得した後の値もつかうでしょうし、
テキスト形式にこだわらなくてもよければ
構造体を利用するのがいいんじゃないでしょうか。

x,y,zの値を持つ構造体を直接ファイル出力することで
ファイルないのどこにほしいデータがあるか計算して直接取得できるようになります。
# sizeof(構造体)*(x*y*z) バイト目
    • good
    • 0

char A[100]


FILE *fp;
for(i=1;i<101;i++)
{
snprintf(A,sizeof A,"A%d.csv",i);
fp = fopen(A,"a");
for(z=1;z<11;z++)
{
for(y=1;y<11;y++)
{
for(x=1;x<11;x++)
{
fprintf(fp,"%d,%d,%d\n",x,y,z);
}
}
}
fclose(fp);
}
    • good
    • 0

1と2を合体させたら



char A[100]
FILE *fp;
int i, x, y, z;
for(i=1;i<101;i++)
{
snprintf(A,sizeof A,"A%d.csv",i);
if((fp = fopen(A,"w"))!=NULL)
{
for(z=1;z<11;z++)
{
for(y=1;y<11;y++)
{
for(x=1;x<11;x++)
{
fprintf(fp,"%d,%d,%d\n",x,y,z);
}
}
}
fclose(fp);
}
}

この回答への補足

なるほど其れもありなんですね…。
でもできれば(1)~(4)を分けて(開いて閉じての動作を分ける)書きたいのですが、どうすれば良いのでしょうか?

補足日時:2010/11/15 18:19
    • good
    • 0

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