C言語のファイル読み込み条件について(要約:条件付きファイル読み込み)

このQ&Aのポイント
  • C言語のプログラムで指定した条件に一致するファイルを読み込む方法について質問です。
  • 具体的には、指定した行数や桁数の条件に一致するファイルのみを読み込むことは可能なのかを知りたいです。
  • また、条件を変えながら複数のファイルを読み込む方法についても教えてください。
回答を見る
  • ベストアンサー

c言語のファイル読み込みについて。

cのプログラムで以下のファイルを読み込む際、指定した行数や桁数などの条件に一致するもののみを読み込むことは出来ますか? 01010101 000250 0003 2008-11-17 16:44 0000 0003-0013-0000 01010101 000250 0005 2008-11-17 11:31 0000 0003-0013-0000 10001000 000150 0002 2008-11-17 16:45 0000 0003-0013-0000 10001000 000150 0004 2008-11-17 11:32 0000 0003-0013-0000                  ・                  ・                  ・ 例えば、 条件1:一桁目が01010101から始まる行の 条件2:13~15桁目(250) を読み込む場合はどうしたらいいでしょうか? 関数を用いて、条件2の桁数指定を変えて他の数値も読み込んで、 それが終わったら次の行に進む形にしたいと思っています。 以下が自分の考えただいたいの構想です。 #include<stdio.h> int Load(); int main(void) { int coad;       //int kakaku,kosuu,mise,jikoku,uriage; //int uriage2[][];       //条件1の指定       printf("商品コード(8桁):"); scanf("%d",&coad); //価格(13~15桁目)、個数(10)、店コード(37)、時刻(33~34)をロード //()内に行数(gyou)、桁数(定数)、条件1(cord)を指定する値 // //kakaku=Load(); //kosuu=Load(); //mise=Load(); //jikoku=Load(); //uriage=kakaku*kosuu; //売り上げ総額を店、時刻ごとに集計↓ //uriage2[mise][jikoku]=uriage[mise][jikoku]+uriage; //gyou=gyou++; // //最下行まで繰り返し return 0; } /* int Load() { } */ わかりにくかったらすいません・・・・ Load関数や()内など、どう記述すればよいでしょうか。 どうかよろしくお願いします。

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

  • ベストアンサー
  • Tacosan
  • ベストアンサー率23% (3656/15482)
回答No.1

「1行ずつ読み込み条件にあてはまる行に対してのみ処理をする」のが簡単じゃないかな.

lana466
質問者

お礼

回答ありがとうございます! 確かにそうですね。 その場合Load関数は具体的にどう記述すればよいかわかる方はいらっしゃいますか? 条件を指定せず全文を読み込む方法しかわからないので・・・ どうかよろしくおねがいします。

lana466
質問者

補足

すいません何か勘違いしてました。 一行ずつ読み込む → 条件に合った場合のみ指定した桁数を変数に入れて処理(for文などで) ということですよね? だんだんできてきました。 ただ、一行ずつ読み込む方法だけがよくわかりません・・・。 変数gyouのみを関数に持っていけばいいとは思っているのですが。 関数内の具体的な記述がわかる方はどうかおねがいします。

その他の回答 (1)

回答No.2

ヒント:fgets

lana466
質問者

お礼

皆様のおかげで無事完成しました! gyouとかいらなかったんですね^^;

関連するQ&A

  • C言語の問題が解けません

    C言語の問題ができなくて困っています。 これが問題文です。 与えられた表の縦・横の値の平均/合計をそれぞれの行・列ごとに求め出力するプログラムを作成しなさい。ただし、縦・横のデータ数は10個未満とし、それぞれの数字は整数とする。また、出力は右詰め6桁で出力することとし、平均における小数点以下は1桁まで表示する。平均行/列および合計行/列がぶつかる個所は、表全体の平均と合計を計算した結果を表示する。 補足として入力された行列数が10未満であることは、プログラム内でチェックすること。 例:20,3→再入力となる(行が9未満でない)  :2,-5→再入力となる(行が負の値) 実行結果例はこんな感じらしいです。 行数(最大9),列数(最大9)をカンマ区切りで入力(行,列):4,4 データをカンマ区切りで行ごとに入力[4行 4列] 52,96,15,20 86,22,35,45 45,78,54,36 16,86,74,55  52 96 15 20 45.8 183  86 22 35 45 47.0 188  45 78 54 36 53.3 213  16 86 74 55 57.8 231 49.8  70.5 44.5 39.0 50.9 - 199 282 178 156 - 815 自分はここまで自力でやったのですがここからが試行錯誤してもできません。このあとどのようにプログラムを書いていけばいいのですか? よろしくお願いします。 #include <stdio.h> int main(){ int gyou,retu,Loop1=0,Loop2=0; int kazu[8][8]; printf("行数(最大9行)、列数(最大9列)をカンマで区切って入力 (行,列):"); scanf("%d,%d",&gyou,&retu); if((gyou<=9)&&(retu<=9)){ printf("データをカンマ区切りで行ごとに入力 [%d行,%d列]\n",gyou,retu); for(Loop2=0;Loop2<gyou;Loop2++){ for(Loop1=0;Loop1<retu;Loop1++){ scanf("%d\n",&kazu[gyou--][retu--]);

  • VBAでテキストファイルを最後まで読み込みたい

    テキストファイル内の文章を最後まで読み込みたいのですが、 do  Line Input #1, gyou  処理1 while 条件 で、条件はどのような記述にすればいいのですか? テキストファイルには、改行コードのみの行や、スペースのみの行が混在しています。 また、行数も常に変動するので、 for~nextで予め回数を指定することも出来ません。

  • C言語について

    #include_<stdio.h> void_gyouRtn(int_hen,int_ln,int_maxl); int_main(void){ __int___hen;__//_辺の長さ(文字数) __int___ln;___//_出力行番号(1,2,..,maxl) __int___maxl;_//_出力行数 __//_最初の入力 __printf("数字2~9を入力してください:"); __scanf("%d",_&hen); __//_規則外の入力への対応 __while(hen_<_2_||_hen_>_9){ ____printf("※入力エラー!!_2~9を入力してください:"); ____scanf("%d",_&hen); __} __//_計算と出力 __maxl_=_3*hen-2;_____________//_行数=3*辺の桁数-2 __for(ln=1;ln<=maxl;ln++)_{___//_行1から逐一実行 ____gyouRtn(hen,ln,maxl);_____//_行の一括処理出力 __} __//_終了 __return_0; } //_行ごとの出力半巾(桁)を与えます //_中心位置±半巾の位置に●を置く予定 int_maxkRtn(int_hen,int_ln,int_maxl){ __int___maxk;_//_半巾の文字数 __//_垂直辺を無視した巾 __if(ln<=maxl/2)_{__//_上半分のとき ____maxk_=_ln-1;____//_lnと共に増加、最初は0 __}_else_{__________//_下半分のとき ____maxk_=_maxl-ln;_//_lnと共に減少、最後は0 __} __//_垂直辺で切る __if(maxk>hen-1)_maxk_=_hen-1; __//_水平辺の半分を加える __maxk_+=_hen/2;____//_hen_が偶数ならmaxk*2==hen ____________________//_奇数なら_maxk*2_==_hen-1 __return_maxk; } //_行の準備と出力を制御、実行します void_gyouRtn(int_hen,int_ln,int_maxl){ __int_kt;___//_桁(文字)位置 __int_maxk;_//_行lnでの半巾、後に行の右端 __int_mink;_//_行での図形の左端位置 __int_cent;_//_縦の中心軸の位置 __maxk_=_maxkRtn(hen,ln,maxl);_//_この行での半巾 __if(hen==2*(hen/2))_{____//_辺が偶数桁 ____cent_=_maxl/2;________//_左半分の右端 ____mink_=_cent-maxk+1;___//_図形の左端 __}_else_{________________//_辺が奇数桁 ____cent_=_maxl/2+1;______//_左と右の間の1桁 ____mink_=_cent-maxk;_____//_図形の左端 __} __maxk_=_cent+maxk;_______//_図形の右端 __//_出力開始 __kt_=_1; __while(kt_<=_maxk){ ____if(1<ln_&&_ln<maxl)_{_//_上下辺以外 ______if(kt_!=_mink_&&_kt_!=_maxk){_//_図形位置以外 ________printf("□"); ______}else{________________________//_図形位置 ________printf("●"); ______} ____}_else_{______________//_上下辺 ______if(kt<mink)_{_________________//_図形位置以外 ________printf("□"); ______}_else_{______________________//_図形位置 ________printf("●"); ______} ____} ____kt++; __} __printf("\n"); } これは添付画像の八角形を表示するプログラムなのですが、これと同様のプログラムで添付画像の*形を表示するプログラムを教えてください。 (「同様」というのは、これ以上の"機能"を一切使わないという意味です。) mainの部分は上記のプログラムとほぼ同じなので大丈夫なのですが、下部の関数部分がわかりません。 関数部分で今考えているアルゴリズムは…  (1)行ごとの出力桁数を与える(中心線±(n-1)/2)  (2)1行目から中心行の前までは、左端・中心・右端に"●"を出力  (3)中心行には、n個だけ"●"を出力  (4)それ以降の行は、(2)と同じ …という感じです。 もちろん、(1)で出力桁数を与える時には、1行目~(n/2-1)行目までは左右1ずつ幅が減り、(n/2+1)行目~n行目までは左右1ずつ増えるようにします。 このアルゴリズムでプログラムを組みたいのですが、どうも難しくてできません。どうか教えてください。

  • EXCELでの有効数字について

    Excelで有効数字桁数を指定して表示させています =FIXED(A1,A2-1-INT(LOG(A1)),TRUE) A1に数値、A2に有効数字桁数 0.09991 を有効数字桁数3で表示させた場合は 0.0999 となり正常ですが 0.09999 を有効数字桁数3で表示させた場合は 0.1000 となり有効数字4桁になってしまします 丸めて繰り上がる場合も3桁(0.100)にするにはどうしたらよいでしょうか よろしくお願いします

  • ファイル入力方法(C言語)

    C言語のファイル入力について教えてください。 入力ファイルinput.txtが以下である時、 *********** abcdefg *********** 2 3 5 6 3 8 1 7 ●最初の3行を無視する ●4行目以降の数値を配列に格納し、表示する (4行目以降は2列で固定、行数は最大100列) 以上の条件でプログラムを作成したいのです。 最初の3行がない入力ファイルinput2.txt 2 3 5 6 3 8 1 7 を入力し、表示するソースコードは以下のように作成できましたが、「最初の3行を無視する」方法が分かりません。 お手数ですが、ご存じの方教えてください。 よろしくお願いいたします。 #include <stdio.h> #include <stdlib.h> int main() { int i,N,a[100],b[100]; FILE *fpi; if((fpi=fopen("input2.txt","r"))==NULL) { fprintf(stderr,"ファイルを開けません\n"); exit(1); } for (N=0; N<100 && fscanf(fpi,"%d %d",&a[N],&b[N]) != EOF; N++); printf("データ行数:%d\n\n",N); for(i=0;i<N;i++) { printf("%d %d\n",a[i],b[i]); } fclose(fpi); return 0; }

  • テーブル(配列)の初期化を外部ファイルに指定

    お世話になっております。 以下は列車の時刻表を検索するCのソースです // ヘッダー省略 #define PRN_PORTD 0x0378 #define PRN_PORTC 0x037a void lightLED( int num, int loc ) { static int table[] = { 0x3F, // 0 0x06, // 1 0x5B, // 2 0x4F, // 3 0x66, // 4 0x6D, // 5 0x7D, // 6 0x27, // 7 0x7F, // 8 0x6F, // 9 }; // table[ num ] で数値から変換 printf("num[%x] port[%x]\n loc[%d]",     able[ num ], PRN_PORTD, loc ); // デバックの為 outb( table[ num ], PRN_PORTD ); outb( loc, PRN_PORTC ); outb( loc | 0x04, PRN_PORTC ); outb( loc, PRN_PORTC ); } // 時刻表の時:分を表示する関数 void digitalLED( int time ) { int ret, four, three, two, one; four = ((time / 1000) % 10); // 4桁目を取り出す three = ((time / 100) % 10); // 3桁目を取り出す two = ((time / 10) % 10); // 2桁目を取り出す one = ((time / 1) % 10); // 1桁目を取り出す ret = ioperm( PRN_PORTD, 4, 1 ); lightLED( four, 0x03 ); // 時の10桁を表示 lightLED( three, 0x02 ); // 時の 1桁を表示 lightLED( two, 0x01 ); // 分の10桁を表示 lightLED( one, 0x00 ); // 分の 1桁を表示 ret = ioperm( PRN_PORTD, 4, 0 ); exit(0); } // ここまでのソースはLEDに表示させる関数です int main(void) { char type; int ret; do {     // ↓テーブル初期化。本来はこれを使用したいのですが。 // static int table[] = { ここで外部ファイル指定 }; / int findtime; // 0000形式に変換後の現在時間 int *search; // テーブル内の検索時間 int h; // 時 int m; // 分 FILE *file; time_t timer; // 現在時刻を取得し地方形式に struct tm *local; time(&timer); // 現在時刻の取得 local = localtime(&timer); // 現在時刻を構造体に変換 h = local->tm_hour; // 時 m = local->tm_min; // 分 findtime = h * 100 + m ; // 現在時間を0000形式へ変換 file = fopen( "jikoku.txt", "r" ); if( file == NULL ) { puts( "jikoku.txtが開けません" ); return 1; } while ( !feof(file)) { fscanf(file, "%d", &*search); printf("%d\n", *search); // 該当時間検索 // for ( search = table ; *search != -1 ; search++ ) {   // ↑時刻表を外部ファイルにしたことによって使わなく   //  なったのですが。。。 if ( *search > findtime ){ break; } } // 結果表示 if ( *search == - 1 ) { // テーブル内の-1に当たったら                              //06:10表示       // ↓table[0]の形に要修正 printf( "06:10\n\n" ); digitalLED( 610 ); } else { digitalLED( *search ); printf( "%02d:%02d\n\n", (*search / 100), // 「時」取り出し (*search % 100) ); // 「分」取り出し } fclose(file); scanf("%c", &type); // Enterで再度プログラム開始 } while (type == '\n'); } テーブルの外部ファイルは以下の様な感じです 610 650 ..... 2310 2350 -1 まだ勉強中の初心者です。汚いソースで申し訳ないです。 これでもみなさんに強力して頂きながら数日かけて、やっとここまでできました。 【困っている箇所】 ・この状態ですと、現在時間の「時」が2桁(10~23時)の場合、セグメン テーションエラーですとの表示で実行できなくなります。 ・コメントになってしまっているテーブル初期化を外部ファイル (jikoku.txt)にしたいのですが(teble[0]→6:10 teble[1]→  6:50 ...の様に。)ファイル名を入れたり色々試したのですがなかなかで きません ・テーブル内で-1に当たったら、6:10分を表示させる箇所も、テーブル使い たいのですが、これも自分でコーディングするとコンパイルが通りませ  ん。 長々と申し訳ありません。ご教授願います。 --前回ご覧頂いた方-- 結局期限を明日までにのばしてもらいました。。

  • エクセルで有効桁を指定して丸める

    以前、↓↓にて http://oshiete1.goo.ne.jp/qa1345491.html 「excelで普通に四捨五入をするとなると  『ROUND』などで小数点以下の桁数を指定しますよね。  そうではなく、有効桁数3桁で四捨五入…例えば、  0.1234ならば0.123  1.234ならば1.23  12.34ならば12.3  123.4ならば123…のように  数字を四捨五入させる関数(?)はあるのでしょうか。」 と質問し、 =ROUND(A1,-INT(LOG(A1))-1 + 3) とか =VALUE(TEXT(A1,"0.00E+00")) といった方法を教えていただいたのですが、 0.1234 なら 0.123 ・・・ 123.4 なら 123 までは同じなのですが、 1234.5 なら 1230ではなく1235 12345.6 なら 12300ではなく12346 つまり、1000未満の場合は以前と同じく有効数字3桁で 1000以上の場合は小数点以下四捨五入としたい場合は、 IF関数で =IF(1000>A1 ・・・のように条件指定してやるしかないのでしょうか。 (A1の部分にも長々した数式が入るもので) 数式がかなり長くなってしまい、見づらいので なにか良い方法があればと思ったのですが…

  • [C言語] 配列が添字の意味を失う理由

    はじめまして。こんばんは。 早速ですが、下記のソースコードは、 配列aの各要素の内容を先頭から順に調べ、最初に0であった要素の添字番号を表示する。 という内容の、C言語のプログラムです。(C++でコンパイルするためmain()はint型に指定) そこで、このプログラムを実行していて腑に落ちない点として、 プログラムの挙動を見る限り、 タイトルに書いたとおり、 「配列が添字の意味を失っている」という事なんです。 普通に配列の添字と考えれば、 while文の条件式は、 int i=0; while(a[i]) { i++; } なので、a[0]になるはずなので、 普通に考えれば 条件式の中身としては  配列a[0] が 配列a[0] になるまでi++をするとなるはずです。 しかしながら、このプログラムは、 初期値に「0」が入っている要素まで探し続けます。 なぜ、 「配列が添字の意味を失うのか?」 どなたか、この疑問にお答えしていただけますと幸いです。 「プログラムの内容」 配列aの各要素の内容を先頭から順に調べ、最初に0であった要素の添字番号を表示する。 「表示結果」 a[2]= 0 「ソースコード」 #include<stdio.h> int main() { int a[]={3,0,7,8,5,5,8}; int i=0; while(a[i]) { i++; } printf("a[%2d]=%2d \n",i,a[i]); }

  • C++のファイルの読み込みの部分で質問があります。

    fp = fopen("enemydata.csv","r");の部分のコードで "enemydata.csv"のファイルを読み込むのですが "r"の部分が何を意味しているのがわかりません。 以下のコードの他にも enemy.cpp enemy.h がありますが関連するものが見あたりません。 "r"の部分のコードは以下に表示します。 よろしくお願いします。 control.cpp #include "pch.h" #include "control.h" CONTROL::CONTROL() { player = new PLAYER; back = new BACK; FILE *fp; ENEMYDATA data[ENEMY_NUM]; char buf[100]; int c; int col=1; int row=0; memset(buf,0,sizeof(buf)); ここの部分→fp = fopen("enemydata.csv","r"); //ヘッダ読み飛ばし while(fgetc(fp)!='\n'); while(1){ while(1){ c=fgetc(fp); //末尾ならループを抜ける。 if(c==EOF) goto out; //カンマか改行でなければ、文字としてつなげる if(c!=','&& c!='\n') strcat(buf,(const char*)&c); //カンマか改行ならループ抜ける。 else break; } //ここにきたということは、1セル分の文字列が出来上がったということ switch(col){ //1列目は敵種類を表す。atoi関数で数値として代入。 case 1: data[row].type=atoi(buf); break; //2列目は弾種類。以降省略。 case 2: data[row].stype=atoi(buf); break; case 3: data[row].m_pattern=atoi(buf); break; case 4: data[row].s_pattern=atoi(buf); break; case 5: data[row].in_time=atoi(buf); break; case 6: data[row].stop_time=atoi(buf); break; case 7: data[row].shot_time=atoi(buf); break; case 8: data[row].out_time=atoi(buf); break; case 9: data[row].x=atoi(buf); break; case 10: data[row].y=atoi(buf); break; case 11: data[row].speed=atoi(buf); break; case 12: data[row].hp=atoi(buf); break; case 13: data[row].item=atoi(buf); break; } //バッファを初期化 memset(buf,0,sizeof(buf)); //列数を足す ++col; //もし読み込んだ文字が改行だったら列数を初期化して行数を増やす if(c=='\n'){ col=1; ++row; } } out: //敵クラス生成 for(int i=0;i<ENEMY_NUM;++i){ enemy[i]=new ENEMY( data[i].type, data[i].stype, data[i].m_pattern, data[i].s_pattern, data[i].in_time, data[i].stop_time, data[i].shot_time, data[i].out_time, data[i].x, data[i].y, data[i].speed, data[i].hp, data[i].item); } } void CONTROL::All() { //int count = 0; //描画領域を指定 SetDrawArea(MARGIN,MARGIN,MARGIN+380,MARGIN+460); back->All(); //プレイヤークラスのAll関数実行 player->All(); for(int i=0;i<ENEMY_NUM;++i){ if(enemy[i]!=NULL){ if(enemy[i]->All()){ delete enemy[i]; enemy[i]=NULL; } } } ++g_count; } CONTROL::~CONTROL() { //プレイヤークラスの解放 delete player; delete back; for(int i=0;i<ENEMY_NUM;++i){ if(enemy[i]!=NULL){ delete enemy[i]; } } }

  • 異なるファイル間のVlookup機能について

    <前提条件> Aファイル:顧客番号(上4桁)、顧客名、 Bファイル:顧客番号(7桁)、顧客名(現在、空欄)、商品コード、商品名 上記がファイル構成となります。 <実現したいマクロ> 「Bファイルの顧客番号(7桁)の次項目である顧客名に、Aファイルの顧客名を入力したい」 顧客番号の桁数が異なるので、どのようにマクロを作成すればよいか、 わかりません。ご教示のほどお願いいたします。

専門家に質問してみよう