ここから質問投稿すると、最大4000ポイント当たる!!!! >>

行m列の任意のデータの処理を行うプログラムで,
列ごとの統計を行うためにm列目のデータを取り出したいのですが,うまくいきません.
どのようなコードを書けばいいでしょうか?

自分で作ってみたのは以下のようなプログラムです(ファイルを開いて→m列目の読み込みの部分)
EOFを使っているためか,行数のiには全データ数が入ってしまいます.


void main (void)
{
FILE* fp;

int i, j;
i=0, j=0;

char FilePath[500];
char Folder[100];
char File[50];

printf("Folder Name:");
scanf("%s",&Folder);

printf("File Name:");
scanf("%s",&File);

sprintf(FilePath,"%s/%s",Folder,File);

if(( fp = fopen (FilePath,"r")) == NULL){
printf("cannot open '%s'\n", FilePath);
exit(1);
} //ここまではうまく動きます


while (fscanf(fp, "%lf", &A[i][0]) != EOF{
i++;
}
while (fscanf(fp, "%lf", &A[0][j]) != EOF){
j++;
}

printf("A[%d][%d]", i, j);
int n, m;              //n,mはこの後for文で使いたいので登場してもらいました
printf("input 'n':");
scanf("%d", &n);
printf("input 'm':");
scanf("%d", &m);

A 回答 (5件)

>どのようなコードを書けばいいでしょうか?



 http://okwave.jp/qa/q7114321.html #3

 読み込み時に配列に格納しないで、
 文字列として1行読み込んでから、(数値化し)配列に格納する例です。

 「m列目のデータ」の前には、m - 1 個の空白があるので、それをカウントし数値化します。
 (ただし、文字列には空白が連続しないこと)

 「実数」を「整数」に、「コンマ」を「空白」に置き換えればよいかと。

 http://www.bohyoh.com/CandCPP/C/Library/fgets.html
 http://www.bohyoh.com/CandCPP/C/Library/atoi.html
    • good
    • 0
この回答へのお礼

回答ありがとうございます!コメントが遅くなってすみません.

配列に格納するタイミングが違うんですね!!
その後何とかプログラムできました.

お礼日時:2012/02/07 01:21

確かにそうなりますね。

>#3

iがどこまで増えて行くのか…というので、バッファオーバーランもありそうなコードではありますが…
A[][]の詳細が不明ですのでなんとも…。
# その後のjについても同様。
で……A[][]にちゃんと読み込めるコードにもなっていなかったりしますね。

エラー処理は別として…ファイルから2次元配列に読み込む。
なんてコードは検索するといろいろ見つかると思います。
    • good
    • 0
この回答へのお礼

回答ありがとうございます.

これではA[][]に読み込めないんですか?!
それ自体「どこがどう」とすぐわからないので,まだまだ勉強不足です….

ネットや参考書などもっと探してみますね.

お礼日時:2012/01/18 23:41

数字以外, より正確には「%lf に適合しない」入力が与えられると


fscanf(fp, "%lf", &A[i][0])
は 0 を返しますが, EOF は負の数である (当然 0 でもない) ので
fscanf(fp, "%lf", &A[i][0]) != EOF
の結果は 1 となり, したがって無限ループになる (現実的には何らかの実行時エラーで異常終了しそう) というのが「正しい動作」ではないでしょうか>#2.

このようなプログラムを作った背景にある「理屈」を説明できますか?

この回答への補足

回答ありがとうございます.
正しい動作の理屈はなるほど!と思えました.

プログラム作成の理屈は,正直説明できません.
参考書などを見ながら使えそうな文法を探して,理解できたものもありましたが
理解できなかったものも
そのままイメージであてはめていったようなものなので….
かなり「こう動いてくれたらうれしい」という感じで書いていった部分はあります.

勉強不足は間違いないのでもっとじっくり取り組もうと思います.

補足日時:2012/01/18 23:36
    • good
    • 0

読み込んでいるファイルの内容はどんな感じなんでしょう?



>while (fscanf(fp, "%lf", &A[i][0]) != EOF{
>i++;
>}
>while (fscanf(fp, "%lf", &A[0][j]) != EOF){
>j++;
>}

の先のwhileループはどこで抜けることを期待しているのでしょう?
# 今は…おそらく全部読み込んでますよね。
データファイルに意図的にエラーになるように書いていない限り。
# たとえば、各行の最後に数字以外が書かれているとか。<もっとも、これだと次のfscanf()次第でオワるのですが…。

この回答への補足

回答ありがとうございます.
データは例えば以下のような形です.
テキスト形式で,特に意味のある数字ではありません.

1 65 3
2 83 71
20 4 39

これだと3行3列なので,このデータはA[3][3]だと判断して
表示させたいです.
fscanf(fp,"%lf",&A[0][j]) では,&A[0][j]としたら
jに列数が入ってくれるのではないかと思ったのですが,違うようで….

補足日時:2012/01/18 23:23
    • good
    • 1

ぐだぐだ言わずにデータを全部読んで必要なところだけ使えばよいだろう。

    • good
    • 0
この回答へのお礼

リプライありがとうございます.

そうなんですが…必要な部分だけ使うために「何列目」という指定がしたいです.
一つの方法にこだわらずにもっと自分でも調べ直してみます.

お礼日時:2012/01/18 23:45

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

このQ&Aを見た人はこんなQ&Aも見ています

このQ&Aを見た人が検索しているワード

このQ&Aと関連する良く見られている質問

QC言語 ファイルの指定された行を表示

こんにちは。
回答お願いします。
今私は作業の高効率化を目指すためプログラムを考えています。
まだぜんぜんできていませんが・・
ファイルの指定された行を表示する関数がないだろうか?
もしくは似たような方法はないだろうかと考えています。

できれば例題とともに教えていただければ幸いです。
具体的にどういう風にしたいのかというと
----test.txt-------
aaaa
bbbbb
cccccc
dddd
eeeeeeee
ffffff
-------------------
というファイルがあったとしたらgetsで4と入れてやったら
四行目のddddが表示されるようにしたいのです。
まだまだ初心者ですのでさっと考えることができません。
どうかご教授お願いします。

Aベストアンサー

★高効率を目指しているの?
・固定長データなら高効率で1行を取得できたりします。
 例えば
 ----test.txt-------
 aaaaa
 bbbbb
 ccccc
 ddddd
 eeeee
 fffff
 -------------------
 という固定長データ(5文字×6行)の場合は
 int no = 4; ←4行目を取得したい時
 fseek( fp, ((no - 1) * 7), SEEK_SET ); ←5文字+\r+\n=『7』
 fgets( buff, sizeof(buff), fp );
 ↑
 これなら行番号で指定した1行を fgets() 関数で取得可能です。
 ※なおバイナリモードでオープンして下さい。
・可変長データの場合は行の先頭のオフセット位置を最初の読み込みで管理します。
 例えば
 ----test.txt-------
 aaaa
 bbbbb
 cccccc
 dddd
 eeeeeeee
 ffffff
 -------------------
 という可変長データ(4,5,6,4,8,6文字)の場合は
 オフセット位置の配列を行数分用意します。→事前に分かれば楽ですね。行数。
 long offset[ 100 ]; ←100行だと仮定
 int max;
 
 for ( max = 0 ; !feof(fp) ; max++ ){
  if ( max >= 100 ){ ←安全対策
   break;
  }
  offset[ max ] = ftell( fp );
  fgets( buff, sizeof(buff), fp );
 }
 ↑
 ここまでがオフセット位置の読み込みです。次は読み出しです。
 int no = 4; ←4行目を取得したい時
 fseek( fp, offset[no - 1], SEEK_SET );
 fgets( buff, sizeof(buff), fp );
 ↑
 これで行番号で指定した1行を fgets() 関数で取得可能です。
 ※やっぱりバイナリモードでオープンして下さい。
・あと行数の指定時に 1~max の範囲になるように補正処理も入れたほうが良いかも。
 例えば
 if ( no < 1 ){
  no = 1;
 }
 else if ( no >= max ){
  no = max;
 }
 ↑
 こんな感じで。
・以上を参考にして下さい。
 下の『参考URL』もどうぞ。

参考URL:http://www9.plala.or.jp/sgwr-t/lib/fseek.html

★高効率を目指しているの?
・固定長データなら高効率で1行を取得できたりします。
 例えば
 ----test.txt-------
 aaaaa
 bbbbb
 ccccc
 ddddd
 eeeee
 fffff
 -------------------
 という固定長データ(5文字×6行)の場合は
 int no = 4; ←4行目を取得したい時
 fseek( fp, ((no - 1) * 7), SEEK_SET ); ←5文字+\r+\n=『7』
 fgets( buff, sizeof(buff), fp );
 ↑
 これなら行番号で指定した1行を fgets() 関数で取得可能です。
 ※なおバイナリモードでオープンして下さ...続きを読む

Qc言語 ファイルから数字を読み込む

c言語初心者です。
forループをつかって、
ファイルから空白で区切られた数字を一つずつ読み込む
プログラムを作りたいのですが、
forループの中をどう書いたらいいかわかりません。

#include <stdio.h>

int main (int argc, char *argv[])
{
char *fileName = argv[1];

FILE *fp = fopen("fileName", "r");

int num;
int i;

for(i=0; i<10; i++){
fscanf(fp, "%d", &num);
printf("%d\n", num);
}
fclose(fp);
}

ファイルの内容は、10個の数字が書かれている設定です。

Aベストアンサー

FILE *fp = fopen("fileName", "r");
は、
FILE *fp = fopen(fileName, "r");
でしょうね。
他はいいと思いますが。

細かいことを言うと、argv[1] を参照する前に、argcの値をチェックすべき。

QC++で、テキストファイルを一行ずつ読み込んで配列に入れたいのですが、

C++で、テキストファイルを一行ずつ読み込んで配列に入れたいのですが、うまくできません!

テキストには -3.0
       1.0
       2.0

・・・などのように一行に一つの数値が入って縦に並んでいます。
それをひとつずつ読み込み、新しい配列(たとえばa[])に順番にいれたいのです。

a[1]=-3.0,a[2]=1.0、・・・と
なるように。

どうか、この初心者にご指導お願いいたします。

Aベストアンサー

fgetsは文字列として読み込みます。これを数値に変換すれば、とりあえずあなたが望んでいることができます。変換はatofを使います。また、atofを使用するときは#include <stdlib.h>が必要です。
例えば
#include <stdlib.h>
  :
double d;
  :
d=atof("-3.0");
とすると、文字列の-3.0が数値の-3.0に変換されdに入ります。

fscanf関数で読み込んでもできますが、書式とデータがあっていないと上手くいかないので注意してください。

Qファイルから読みこむ方法

Unix C++でファイルから、特定の行を読みこむことは可能でしょうか。
例えば、5行目から最後の行まで。10行目から20行目。等。

Aベストアンサー

 CやC++には、テキストファイルから指定した行を読み込むという関数は用意されていません。
 ですので、ファイル先頭から行単位で読んでいき、読んでいる行数を変数でカウントしながら、目的の行だけ配列に入れるなどの処理を行うことになります。

 行単位の読み込みは、istream系オブジェクトに用意されたgetlineメソッドで行えばよいでしょう。

#include <iostream.h>
#include <fstream.h>

int main(void)
{
  ifstream fin;
  int s = 10;   // 先頭からなら 1 を指定する
  int e = 20;   // 末尾までなら -1 を指定する
  const int bufsize = 256;
  char buf[bufsize];

  fin.open("xxx", ios::in | ios::nocreate);
  if (fin.fail()) {
    cerr << "ファイルを開けません\n";
    return 1;
  }
  for (int i = 1; i < s; i++)   // 読み飛ばし
    fin.getline(buf, bufsize);
  for (int i = s; i<=e || (e==-1 && !fin.eof()); i++) {
    fin.getline(buf, bufsize);
    cout << buf << endl;
  }
  fin.close();

  return 0;
}

 ところで、これまでの回答には何の補足もお礼もありませんが、解決はしたのですか?未解決なら分からないところを書かないと、新しい回答は書きにくいものですよ。

 CやC++には、テキストファイルから指定した行を読み込むという関数は用意されていません。
 ですので、ファイル先頭から行単位で読んでいき、読んでいる行数を変数でカウントしながら、目的の行だけ配列に入れるなどの処理を行うことになります。

 行単位の読み込みは、istream系オブジェクトに用意されたgetlineメソッドで行えばよいでしょう。

#include <iostream.h>
#include <fstream.h>

int main(void)
{
  ifstream fin;
  int s = 10;   // 先頭からなら 1 を指定する
...続きを読む

Qファイルの特定行の抽出

C++言語についての質問です。

C++を利用して下記の処理を考えています。

下記のようなテキストファイルから、「名前」で始まる行だけを
抽出して、別のテキストファイへ書き込みを行います。
また、その際に”「名前」の表記”+”スペース文字”は削除します。

-----------------
住所 東京都
名前 AAAAA
年齢 15才
-----------------
住所 神奈川県
名前 BBBBB
年齢 20才
-----------------
<略>

実行後に出力されるテキストファイルには、

AAAAA
BBBBB

と記載されるように処理を行いたいです。

初心者のため、実現可能かも分かっていません・・。
お手数ですが、アドバイスをお願いします。

具体的な方法についても記載して頂けると助かります。

よろしくお願いします。

Aベストアンサー

No4です(改修←早っ、おちつけ年寄り)。
>また、その際に”「名前」の表記”+”スペース文字”は削除します。

スペース文字として、「半角または全角の1つ」としました。

while( NULL != fgets( cBuf, 255, fp1 ) ){

if( strstr( cBuf, "名前 " ) ) fprintf( fp2, "%s", &cBuf[5] );
if( strstr( cBuf, "名前 " ) ) fprintf( fp2, "%s", &cBuf[6] );
}
こんなのじゃあ質問しないか簡単すぎて・・・。C++に書き換えろ、ということかなぁ(ご質問主旨に沿っていないのではと不安)。
No1回答者さんがいわれるように「がんばって」なくて申し訳ない。

Qc言語でのfscanfについて

例えば
------------------
ほげほげ1
ほげほげ2
1,2
2,4
3,8
4,16
------------------
というデータファイルがあったとき3行目からのデータだけを抽出するにはc言語のfscanfでどのように書けばいいでしょうか?
簡単にでかまわないので、どなたか教えてください。

Aベストアンサー

1行目、2行目に空白がないのであれば、

int x,y;
fscanf(fp,"%*s %*s %d,%d ",&x,&y);

で、xに1、yに2が入ります。

QC言語 配列の長さの上限

C言語で配列Array[N]の長さNの上限っていくらなんでしょうか?
もし可能なのであれば上限を2147483647にしたいのですが、方法を教えてください。

Aベストアンサー

そもそもWindowsの32bit版はアプリが仮想メモリ空間を2GBしか使えません。2GBを超えるには64bit版が必要です。
たとえ64bit版OSだとしても添え字が2147483647って、単純なintの配列だとしても4x2147483647=8GB必要ですね。実メモリ16GBとかのPCを用意しますか?
そもそも配列で2147483647個必要なアルゴリズムに問題ありだと思います。

Qエクセル形式のファイルの読み込み

C言語で、エクセル形式のファイルの読み込みの仕方を教えてほしいです。

CSV形式のファイルにするまでは分かっているのですが、そこからどのように読み込めば良いのか分かりません。

何か分かりやすく解説されている本、またはサイトがありましたら教えて下さい。

テキスト形式のファイルの読み込みはやった事があるのですが、同じようなやり方でできますか?

Aベストアンサー

大体以下の様なフローにします。
1)CSVファイルをテキストファイルの読み込みと同じようにOPENする
2)テキストファイルを1行読み込む
3)読み込んだ行を","で分離して、セルデータを取り出す。
4)1行の最後まで、3)を続ける
5)ファイルの終わりまで2~4)を続ける
==>
 此処で、文字列の分離する方法として、c言語ならばstrtokが便利に使用できます。

<strtok例>
#include <stdio.h>
#include <string.h>

int main(void)
{
char str[] = "ABCD,ef,1234,G";
char *tp;

/* ,を区切りに文字列を抽出 */
tp = strtok( str, "," );
puts( tp );
while ( tp != NULL ) {
tp = strtok( NULL," ." );
if ( tp != NULL ) puts( tp );
}

return 0;
}
【実行結果】
ABCD
ef
1234
G
(注意)
 エクセルデータをcsvに出力した場合、データ内に,が有ったりした場合、上記の例ではうまく行きません。エクセルデータにはどの様な文字が含まれているか、事前に調査する事が必要です。また、文字列など""で囲まれていたりしますので、分離したデータから""を取り除くなどの処理が必要かも知れません。
 データに,がある場合、区切りを<tab>にしたテキスト出力をして、データを読み込む方式もあります。

参考URL:http://www9.plala.or.jp/sgwr-t/lib/strtok.html

大体以下の様なフローにします。
1)CSVファイルをテキストファイルの読み込みと同じようにOPENする
2)テキストファイルを1行読み込む
3)読み込んだ行を","で分離して、セルデータを取り出す。
4)1行の最後まで、3)を続ける
5)ファイルの終わりまで2~4)を続ける
==>
 此処で、文字列の分離する方法として、c言語ならばstrtokが便利に使用できます。

<strtok例>
#include <stdio.h>
#include <string.h>

int main(void)
{
char str[] = "ABCD,...続きを読む

Qファイル出力の場所を指定

現在C++にてhtmlファイルを出力するプログラムを作っているのですが、出力場所を指定することはできるのでしょうか?(現在はそのプログラムソースが保存されている場所と同じファイル内に出力されますが、それをデスクトップに出力するなど。)
もし、方法がありましたら、教えてください。
ソースや参考HPのURLなどのせていただけたらありがたいです。
環境はVisualStudio.NET2003です。
よろしくお願いします。

Aベストアンサー

単にファイル名の前にパスを指定する。

絶対パス指定
fp=fopen("c:/temp/test.txt","w");

相対パス指定
fp=fopen("./hoge/test.txt","w");


デスクトップはOSやユーザによって場所が異なるので、少し面倒です。
XPの場合環境変数を利用してこんな感じで出来ると思います。

例:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

void main(void)
{
FILE *fp;
char fname[1024];
strcpy(fname,getenv("USERPROFILE"));
strcat(fname,"/デスクトップ/test.txt");
fp=fopen(fname,"w");
//処理
fclose(fp);
}

Qカンマ区切りのデータを配列に読み込みたい

趣味でゲームを製作しているのですが、その中で、
マップデータのテキストファイルを二次元配列に読み込むようにしています。
データファイルは、カンマ区切りで、例えば、
1,2,3,4,5
5,4,3,2,1
1,2,3,4,5
というようになっています。

fp=fopen(path,"r");
for(j=0; j<3; j++)
{
for(i=0; i<5; i++)
{
char c;
do{c=(getc(fp));}
while(c==','||c=='\n'||c=='\r');
map[j][i] = c-'0';
}
}

配列の各要素に読み込む中身が、0~9など1文字に限られている場合、このgetc()を使う方法で問題ないのですが、0~255など、文字数がまちまちになると、1文字を取り出すgetc()ではできなくなってしまいます。

これがどうすれば可能になるのか、情けないのですがちょっと思いつかないので、アドバイスを頂ければ幸いです。

Aベストアンサー

少し手を入れたらできそうですね。


{
char c;
do{c=(getc(fp));}
while(c==','||c=='\n'||c=='\r');
//-----------追加-----ここから
// int calc; の宣言要
calc = 0;
do { calc = (c - '0') + (calc*10);}
while(isdigit(c=getc(fp)));
//-----------追加-----ここまで
map[j][i] = calc;
}


このQ&Aを見た人がよく見るQ&A

人気Q&Aランキング