行の移行と取得についてお願いします。

[戻る]
桂華 2002/06/05(水) 15:47:51
こんちには。
Cでプログラムを作成しています。
バージョンはVC6.0を使用しています。

あるテキストファイルがあります。
改行方式で
4
5
6
7
8
9
-----
-----
5
6
7
8
のような形式でかかれています。

ここで、もし'4'がみつかればこれを1行目とし、
この行からの4行目と5行目の値(上の表で言えば7と8)を取得したいのですが、
当方全くの初心者で方法が見つからず困っています。

ご存知でしたらすみませんがご教授願えませんでしょうか?
よろしくお願いします。

PAI 2002/06/05(水) 16:38:16
具体的な技術ではなく、方針としてどうしていいかわからない、ということですか?

改行ごとに読み込むようにして、'4'が見つかったら3回読み飛ばす、

じゃだめですか?

桂華 2002/06/05(水) 16:57:50
PAI様、早速のレスポンス感謝しております。

  説明不足で申し訳ありません。
  具体的な技術が分からないのです。

  テキストファイルの中で'4'が見つかったら
  '4'以降の列を読み込み変数(配列?)に保存しておいて、
  '4'から4行目に入っている数字を取得して別ファイルに出力する処理を
  書きたく思います。

  また、5行目も同じく、4行目を出力するファイルとは違いますが、
  また別ファイルに5行目を出力する処理を書きたいので、
  質問させていただきました。

  '4'から4行目までの間は変数に保存したいので読み飛ばす事は
  できません。

  また、大変ややこしいですが、このテキストファイル内に'4'はいくつかあり、
  '4'が出てきたら、次に'4'が出てくるまで、間に書かれているデータを
  別ファイルに書き出す処理を行いたいのです。

  そこで、まず'4'が出てきた後の処理を書きたかったのですが、
  具体的にどう書いたら良いか分からなくなり、質問させていただきました。

  もしよろしければご教示くださいませ...。

PAI 2002/06/05(水) 18:21:14
まとめましょう。

前提:入力ファイルがあり、そこには行志向でデータが保存されている。

1、行ごとに値を取得する
2、特定の値(4)が出てきてから、
  再度出てくるまで値を一時的な変数に保存する。
3、保存された値に対し、特定の動作を行い、
  複数のファイルへと出力する。
4、ファイルの終わりまで、前述の特定の値が出るごとにくりかえす。


ということでいいですか?

そして、特にさしあたって困っているのは、
特定の値が出てきてから再度出てくるまでの間の値を保存するには
どうしたらいいかがわからない。

ということで、いいんでしょうか?

beginner 2002/06/05(水) 18:43:20
4が初めて出てきたら、それ以降をあるルールに従ってファイルに書き出して
2回目に4が出てきたらその処理を止める、ってことですか?

while(1){

  fgets(***);
  if(読み込んだものが「4」でない)continue;
 else if(ファイルの終端)break;

  hoge(fp);//

}

void hoge(FILE *fp)
{
  int count = 0;

  while(1){
    fgets(***);
    if(読み込んだものが「4」)break;

    count++;
    //読み込んだものを書き出す処理//
    if(count == 4||count == 5){
      ファイルAに書き出す
    }
    else{
      ファイルBに書き出す
    }
}

かなり適当に書きました。ロジックは

最初はとにかく読み飛ばします。
4が見つかったら次の4が出てくるまで、希望の処理をする関数を呼びます。
この時点で処理を止める判定を下す4を読み込んでるので、同じことを繰りかえします。

です。このまま使っても多分バグだらけっていうかロジックどおりに動くかも
疑問ですが参考になるようでしたら、参考にしてください。


#まずは処理させたいことを箇条書きにする
#次にそれらを文章にしてみる
#とにかくコーディングしてみる

beginner 2002/06/05(水) 18:49:22
>    //読み込んだものを書き出す処理//
>    if(count == 4||count == 5){
>      ファイルAに書き出す
>    }
>    else{
>      ファイルBに書き出す
>    }

違うか。

if(count ==4){
  ファイルA
}
else if(count == 5){
  ファイルB
}

か?しかも

>'4'以降の列を読み込み変数(配列?)に保存しておいて、
 
の処理は含まれてないですね(^^;
すいませんです。

桂華 2002/06/05(水) 18:57:18
たくさんレスポンスしていただけて嬉しいです。
凄く分かりにくい説明を書いてしまい申し訳なく思っています。
すみません!!!

PAI様、分かりやすくまとめてくださってありがとうございます。
あれから必死でコーディングし、何とか'4'が出てき、その後の行を
判断する所まではできました。

そこで、今差し当たって困っている事は、まず最初の'4'を見つけ、
次の'4'が出てくるまでのデータを一旦新ファイルに書き出し、
次のに4'が再び出てきたらさらに次の'4'が出てくるまでのデータを
新ファイルに書き出す処理です...。

beginner様、コード付きで分かりやすく説明してくださってありがとうございます。
beginner様からのアドバイスでごちゃごちゃしていた私のコードがきちんと
整理できそうです。

本当に分かりにくいあいまいな説明で申し訳ありませんでした。
以後はもっと整理してコードも書くようにいたします。

さなえ 2002/06/05(水) 19:21:22
簡単ですがこんな感じでどうでしょう・・・
for(;;)
{
 4が見つかる
   関数A(FILE*);
}

関数A()
{
  書き出し用ファイルを開く
  for(;;)
  {
    読む
    4だったら break;
    書く
  }
  書き出し用ファイルを閉じる
}

関数Aに入ってすぐの読み込みは4の次の行です。
関数Aから戻ってすぐの読み込みも4の次の行です。ややこしけど。

あと、途中で前に読み込んだ行に戻る場合はftell,fseekなどを使います。

PAI 2002/06/05(水) 19:33:14
あ、ファイルに書きだすようにしましたか・・・
C++になっちゃうけど、std::vectorで書いてみちゃったんで、まあ参考にでもなれば、

template < typename T >
void testFunc2( vector<T>& data )
{
    // cout << "--------" << endl;
    // copy( data.begin(), data.end(), ostream_iterator<T>(cout, "\n" ));
    
    if( data.size() > 3 ){
        cout << " 4行目" <<data[2] << endl;
    }
    if( data.size() > 4 ){
        cout << " 5行目" <<data[3] << endl;
    }
}

template < typename T >
bool testFunc(T sep )
{
    // ファイルを開く
    ifstream fin("test.txt");
    if( ! fin.good()) return false;
    
    // 最初の区切りを探す。
    T tmp;
    while(fin >> tmp){
        if( tmp == sep ) break;
    }
    if( fin.eof() ) return false;


    // 区切りごとに分けながらあと処理を呼ぶ。
    vector<T> data;
    data.push_back( tmp ); // 区切りそのもの
    
    while( fin >> tmp ){
        
        if( tmp == sep ){
            testFunc2( data );
            data.clear();
            data.push_back( tmp );
            continue;
        }
        data.push_back( tmp );
    }

    // 余った部分
    if( ! data.empty() ) testFunc2( data );

    return true;
}


int main(int argc, char* argv[])
{
    if(! testFunc( 4 )){
        cout << "??" << endl;    
    }
    return 0;
}

PAI 2002/06/05(水) 19:35:48
#include <fstream>
#include <vector>
#include <iostream>
#include <algorithm>
using namespace std;

が必要ですが・・・

桂華 2002/06/06(木) 15:34:29
PAI様、さなえ様、beginner様、ご回答ありがとうございます。
結局今だ完成に至っておらずお返事が遅くなってしまい
大変申し訳ありませんでした。

'4'を見つけ、そこから4行目と5行目を判断して
ファイルに書き出す処理は何とか作成できました。

その後次に'4'が出てくるまでの間のデータを別ファイルに
書き出さなければいけないのですが、
まず4行目まで一旦配列に格納して別ファイルに書き出しました。

そして5行目以降をこのファイルに続けて書き出して
いきたいのですが、書き込み行の取得方法が分からず
悩んでいます。

4
5
6
7
↑一旦4行目までファイルに書き込みました。
その後、5行目を取得した後、次の'4'が出てくるまでの間の
データをこれに続けて書き加えていきたいのです。

何かアドバイスをお願いいたします。

PAI 2002/06/06(木) 16:29:38
ファイルはどうやって開いてます?
最後に追加するだけだったら追記モードで開けばOKですよ。

fstream だったら ios::app | ios::out
fopen は "a+" だったかな?

桂華 2002/06/07(金) 11:56:52
[[解決]]
PAI様、返信が大変即なってしまいました。
お詫び申し上げます。

追記モードで無事作成する事ができました。
もっとMSDNやヘルプを詳しく見るようにしなければいけませんね。

長い間アドバイスしてくださってありがとうございました。

古いスレッドには追加発言できません。