こんにちはゲストさん。会員登録(無料)して質問・回答してみよう!

解決済みの質問

C言語で文字列をポインタ名にしたい

C言語で文字列をポインタ名にしたい



題名のとおりですが、C言語で文字列をポインタ名にする方法はありますか?

具体的にはxの配列の個々の要素を、計算回数による計算結果の推移をファイルに出力したいと考えています。
ファイル名は「test_x_1.data」、「test_x_2.data」、…「test_x_50.data」のようになっています。
(要素分のファイルを作成するということです。)
ここでそれぞれの「test_x_1.data」、「test_x_2.data」、…「test_x_50.data」には、
x[i]の計算回数と計算結果が格納されていますが、
現状では、fopenとfcloseを計算回数分繰り返しているため、計算時間がかかってしまっています。
よって、計算を行う前の最初にfopen、最後にfcloseを行うようにしたいのですが、
ファイルポインタを開く作業を手動で行うと、xの要素分ファイルポインタを用意しなくてはならなくなります。
(現状のようにファイルポインタを使いまわすのではなく、
要素分(=ファイル数)のファイルポインタを、常に開きっぱなしにしたいということです。)
そのため、文字列をポインタ名にすることで、その作業を自動で行えるようにできればと考えています。

実際にchar型の配列が文字列になっているため、「FILE *buf」のように宣言しようと試みたのですが、
bufは既に文字列型の配列として宣言されているため、使用することができませんでした。
(文字列そのものをファイルポインタ名にできなくても、
この場合、要素数分のファイルポインタを自動で用意できれば問題ないのですが…)

下は簡単なプログラム例です。詳しい方のご助言を戴ければ幸いです。
よろしくお願い致します。


--------------------------------------------------------------------------------
#include <stdio.h>
#include <stdlib.h>
#include <math.h>

#define CAL 10000 /*計算回数*/
#define ELE 50 /*配列の要素数*/
#define NUM_CHAR 20 /*char型で確保する文字数*/

int i,j,n; /*forループ用*/
double x[ELE]; /*計算結果の配列*/
char buf[ELE][NUM_CHAR]; /*文字列*/

int main(void){

char filename[] = "test_x_";
char fileext[] = ".data";

/*「test_x_数字.data」という文字列の出力*/
for(i=0;i<ELE;i++){
sprintf(buf[i],"%s-I%d%s",filename,i,fileext);
}

for(n=1;n<CAL;n++){

/*計算部分*/
for(i=0;i<ELE;i++){
x[i] = 2*n+i;
}

/*ファイルに出力*/
for(i=0;i<ELE;i++){
FILE *fp; /*このファイルポインタ名を要素数分用意したい*/
if(n==1){
if((fp = fopen(buf[i],"w"))==NULL){
printf("The program can't create a file. : buf[i] \n");
exit(1);
}
}
if(n>=2){
if((fp = fopen(buf[i],"a+"))==NULL){
printf("The program can't read a file. : buf[i] \n");
exit(1);
}
}
fprintf(fp,"%d %f\n",i,x[i])
fclose(fp);
}
}
return 0;
}
--------------------------------------------------------------------------------

投稿日時 - 2010-12-07 16:35:04

QNo.6369078

すぐに回答ほしいです

質問者が選んだベストアンサー

FILE* も配列にしてファイル名作成時に一緒に開いたらよさそうですがfopenは同時に開ける数に制限があるので注意しないといけません
FOPEN_MAX個は開けるのが保証されています

FILE* fp[ELE];
/*「test_x_数字.data」という文字列の出力*/
for(i=0;i<ELE;i++){
sprintf(buf[i],"%s-I%d%s",filename,i,fileext);
if((fp[i] = fopen(buf[i],"w"))==NULL){
printf("The program can't create a file. : buf[i] \n");
exit(1);
}
}

投稿日時 - 2010-12-07 17:10:04

お礼

なるほど。ポインタ自体を配列にすればいいわけですね。シンプルで参考になりました。
注意点まで挙げていただき、ありがとうございます!
ポインタ数の総和とFOPEN_MAXの数を書き出して問題ないか確認することにします。

投稿日時 - 2010-12-08 02:24:17

ANo.1

このQ&Aは役に立ちましたか?

1人が「このQ&Aが役に立った」と投票しています

回答(4)

ANo.4

No.3です。
他になさそう。・・・ではありませんでした。

もう1つの中間ファイルを使う方法 あるいは、CAL*ELEの2次元配列を使う方法

もありました。

中間ファイルを使う場合は、計算結果の行頭に、nの値を追加したデータ行を

ファイルに一旦全て出力して、全ての計算が終わったら、

再度読み込んで振り分けるという方法はどうですか?
(もちろん、一致するnのみを抽出するネストしたELE回のループによって行います)

投稿日時 - 2010-12-07 20:00:04

お礼

一度書きこんでから再度読み込む発想はありませんでした。
参考にさせて頂きます。ありがとうございました。

投稿日時 - 2010-12-08 02:29:49

ANo.3

確かに、遅くなるプログラムのようですね。

ファイルのオープンクローズをCAL*ELE回行うようになっている点を
見直してはどうでしょうか?

つまり、ELE回の大きいループの中で、CAL回ループするように組み替えれば、

オープンクローズはCAL回で済むと思います。
(オープンモードのオプションの判定も無くなります)

質問のプログラムの部分しか見てませんので、何かこうする意味があれば

仕方ないですが、他の方のおっしゃるようにするしかありません。

投稿日時 - 2010-12-07 18:48:04

ANo.2

> C言語で文字列をポインタ名にする方法はありますか?

残念ながら、ありません。

しかし、ファイル名が連番で管理されているのであれば、ファイルポインタの配列を用意するという手は有効だと思います。

例えば、
 FILE *fp[ELE];
として、
 if((fp[i] = fopen(buf[i],"w"))==NULL){
とするとか。

投稿日時 - 2010-12-07 17:26:48

お礼

順番の関係でNo.1の方をベストアンサーにいたしましたが、
C言語では文字列をポインタ名にすることができないという点で、参考になりました。
ありがとうございました!

投稿日時 - 2010-12-08 02:26:12

あなたにオススメの質問