• ベストアンサー

C言語でテキストファイルから読み込み

下のような形でデータを保存してあるテキストがあるんですが、このうち四行目以降の6個のデータを読み込んで、別のテキストファイルに書き出したいんです。しかし、四行目以降はまったく同じ書式でかかれているのですが、三行目までが空白だったり、文字が混じっていたりで上手くほしいデータを抽出するコードがかけません。何かいい方法はないでしょうか?ご教授よろしくお願いします。 例) データ番号 1    (スペースはタブ。以下同様。) (空白) (空白) 1.2 2.4 0.0 4.4 3.6 0.0 1.3 2.5 0.0 3.2 2.5 0.0 ・ ・ ・ (以下略)

  • ukyn
  • お礼率33% (2/6)

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

  • ベストアンサー
  • samtomsan
  • ベストアンサー率55% (1060/1897)
回答No.5

下記でできませんか。 while( (c=fgetc(fp)) != '\n' ) ; /* 1行目 */ while( (c=fgetc(fp)) != '\n' ) ; /* 2行目 */ while( (c=fgetc(fp)) != '\n' ) ; /* 3行目 */ while( ( ret = fscanf( fp, "%lf %lf %lf %lf",&karif1, &karif2, &karif3, &karif4 ) ) != EOF ){ f1=karif1; f2=karif2; f3=karif3; f4=karif4; printf( "%lf %lf %lf %lf¥n",f1, f2, f3, f4 ); }

ukyn
質問者

お礼

ご回答ありがとうございます。 お陰様で無事読む込むことができました。 何度もお手数おかけして申し訳ありませんでした。 本当にありがとうございました。

その他の回答 (5)

  • kmee
  • ベストアンサー率55% (1857/3366)
回答No.6

fscanf のマニュアル、よくよみましょう。 fscanfでは、改行は基本空白と同じです。 たとえば > fscanf( fp, "%lf %lf %lf %lf",&karif1, &karif2, &karif3, &karif4 ) ですが、"%lf"4つ並べて「1行」読んでるつもりなのでしょうが 1.3 1.3 1.4 1.4 も 1.3 1.3 1.4 1.4 も 1.3 1.3 1.4 1.4 も全部同じに読み込みます。 ・読み書きに同じFILE *を使っている限り、fgetcとかfscanfを混ぜて使っても問題ありません。 fgetcで読んだ後にfscanfを使えば、fgetcで読んだ続きからfscanfが処理されます。 ・行単位で処理したかったら、1行ずつfgets等で読みこんで、その文字列を処理するのが確実です。

ukyn
質問者

お礼

fscamfについて誤解していました。 ファイルポインタや文字の取り扱いについてまた勉強してみたいと思います。 ご回答してくださってありがとうございました。

  • samtomsan
  • ベストアンサー率55% (1060/1897)
回答No.4

ANo.3です。 最初の三行は個数が同じでないのですね。 ANo.2さんの空読みをしてから whileを実行し、wileの中のif(idt > 2)を止めて四行目からの処理でできませんか。 先にも書きましたように、fgetsを使って行単位で読み込み、最初の三行は無視して四行目からsplitしてデータを一行に含まれる個数に分けてから処理する方が柔軟性があって楽ではないかと思います。

  • samtomsan
  • ベストアンサー率55% (1060/1897)
回答No.3

空読みはANo.2さんが回答されていますが、お示しの所のように書きたいのでしたら下記でしょうか。 「%lf」か「%f」かはデータと変数の型によります。  while(( ret = fscanf(fp,"%f,%f,%f,%f,%f,%f\n",&kari[0],&kari[1],&kari[2],&kari[3],&kari[4],&kari[5])) != EOF)  {    // 4行目以降を読み込む    if(idt > 2)    {      ch1[i]=kari[0]; //データ列1つ目      ch2[i]=kari[1]; //データ列2つ目      ch3[i]=kari[2]; //データ列3つ目      ch4[i]=kari[3]; //データ列4つ目      ch5[i]=kari[4]; //データ列5つ目      ch6[i]=kari[5]; //データ列6つ目    }    //ループカウンタをインクリメント    idt++;    //    // データ6個の処理    //  } fgetsを使ってsplitした方が柔軟性はあると思いますが。

ukyn
質問者

補足

再三申し訳ないのですが、やはりどうもうまくいきませんので、私が作成したコードを見てもらえないでしょうか? と言いますのも、テキストの中身が(例1)だと上手くいくのですが、(例2)だと一行目に文字列が入っている時点でデータの型が一致しないためか、まともな数字が代入されないのです。 よろしくお願いします。 (例1) 1.3 1.3 1.4 1.4 1.3 1.3 1.4 1.4 1.3 1.3 1.4 1.4 1.3 1.3 1.4 1.4 1.3 1.3 1.4 1.4 (例2) a (空白) (空白) 1.3 1.3 1.4 1.4 1.3 1.3 1.4 1.4 1.3 1.3 1.4 1.4 (コード) #include <stdio.h> int main(void) { FILE *fp; char *fname = "space.txt"; int ret; double f1,f2,f3,f4; int idt=0; double karif1,karif2,karif3,karif4; fp = fopen( fname, "r" ); if( fp == NULL ){ printf( "%sファイルが開けません¥n", fname ); return -1; } while( ( ret = fscanf( fp, "%lf %lf %lf %lf",&karif1, &karif2, &karif3, &karif4 ) ) != EOF ){ printf("idt=%d\n",idt); if(idt>2){ f1=karif1; f2=karif2; f3=karif3; f4=karif4; printf( "%lf %lf %lf %lf¥n",f1, f2, f3, f4 ); } idt++; } fclose( fp ); }

  • kmee
  • ベストアンサー率55% (1857/3366)
回答No.2

なんか、難しく考えすぎてないですか? 例ですが while( (c=fgetc(fp)) != '\n' ) ; /* 1行目 */ while( (c=fgetc(fp)) != '\n' ) ; /* 2行目 */ while( (c=fgetc(fp)) != '\n' ) ; /* 3行目 */ などと3回'\n'が来るまで「読みこむだけ」で、その続きから読めば4行目から読み込めます。 上のをそのまま使うと、行数が変わったり、3行未満だったりすると面倒ですが。

ukyn
質問者

補足

ご回答ありがとうございます。 おっしゃる通り少し難しく考えすぎているのかもしれません。 しかし、ひとつ気になることがあります。 私はテキストファイルを読み込む際、fscanf関数を使用しています。 fscanfはテキストの先頭から読み込むと思うのですが、 だとすると三回¥nを読み込んでから、fsancfで四行目以降を読み込む、という技は 使えないと思うのですが、kmee様が仰っている方法はそもそもfscanfを使用しない方法なのでしょうか? できることならば、なにかコードを追加することでテキストの先頭から三行は飛ばすという命令を加えて、 while( ( ret = fscanf( fp, "%f %f %f %f %f %f",&n1, &n2, &n3, &n4))!= EOF ) といったコードで四行目以降から読み込み開始できればと思っています。

  • samtomsan
  • ベストアンサー率55% (1060/1897)
回答No.1

どちらが求める回答でしょうか。 > 四行目以降の6個のデータを読み込んで、別のテキストファイルに書き出したいんです 最初の三行は空読みすればすみますね。 > 三行目までが空白だったり、文字が混じっていたりで上手くほしいデータを抽出するコードがかけません 空白を区切りとしてsplitされたらいかがでしょうか。 http://d.hatena.ne.jp/mohayonao/20090227/1235742693

ukyn
質問者

補足

さっそくのご回答ありがとうございます。 4行目以降のデータがほしいのですが、最初の三行をから読みとはどうすればよいのでしょうか? ちなみに私が最初に考えていたのは以下に紹介されている方法でしたので、こちらをベースにできる方法だと理解しやすく非常に助かるのですが・・・。よろしくお願いします。 http://okwave.jp/qa/q6975702.html

関連するQ&A

  • テキストエリア

    テキストエリア内にデータ(HTMLソース)を入力し、HTMLファイルとして保存します。 しかし、問題がいくつも出てしまいました。 1.空白の処理・・・半角全角とも空白があるとそこまでのデータしか送れません。 2.複数行のデータが送れない。改行すると、1行目しかデータが送れません。 3.特殊文字。<や>などの文字があると、きちんと送れません。 どうしたらデータをそのままの形で送れるでしょうか?

    • ベストアンサー
    • Perl
  • エクセルで、テキストデータと数値データを加工したい

    いつもお世話になります。 エクセルに、下記の表があります。 商品コード 商品名 空白行 幅 高 奥行 4901234567890 A商品 30 60 20 このデータを、 商品コード 商品名 空白行 幅 高 奥行 "4901234567890" "A商品" "" 30 60 20 という形にマクロで自動的に加工したいのです。 やりたいことをまとめると、 ・商品コード(8ケタ~13ケタの数値)と、商品名などのテキストデータには、データの頭と後ろにタブをつけたい。 ・サイズ情報など、3ケタ程度の数値はそのままにしたい。 ・空白行には、タブを2コ入れたい。 以上の3つを同時に行うマクロの作成は可能でしょうか。 以上宜しくお願い致します。

  • VBAでテキストファイルの読み書き

    ExcelVBAで、テキストファイルの読み込みと書き換えについて教えてください。 現在は「LINE Input」で一行を読み込み、MIDで文字列を読み込んだり、書き換えていました。 が・・・それは「1文字目から5文字目まで」と決まった位置で書いてあるというのが大前提です。 でも、いつもそうとは決まっていません。当然いろいろな形があるわけです。 500▲▲6.54▲99999▲▲▲▲DDD▲▲ 3000▲40▲▲▲▲PPP▲60.45▲▲ AAA▲CCC▲80.45▲666▲777▲ (見にくいのですが▲はスペースです)などかなり不規則に並んでいる物があります。 「1行目の3番目の数値」(この場合だと99999)をうまく取り出すにはどうしたら良いのでしょうか? 当然その前の500と6.54はどんな数値になっているかわかりませんし、スペースの数も不規則です。 取り出す値の桁数だって決まっている訳じゃありません。 この場合は▲をスペースとしていますが、当然タブで区切られていることも予想できます。 かなりいい加減なデータテキストファイルなのですが、決まっているのは「1行目の3番目の数値」ということだけなのです。 一文字一文字、スペースかタブか文字か?と認識する必要があるのはわかるのですが、切り貼りがうまくできないのです。 文字とスペース(もしくはタブ)を認識してそれを変数に取っておいて、文字をくっつけたりするのでしょうが・・・なかなかうまくいきません。 変数とかもいろいろ用意しているのに・・・根本ができていないようです。 何かわかりやすくて、いい方法を教えていただけないでしょうか?昨日はずっとこれをしていたのですが、目当ての物を取り出せずにいました。どうかお力をお貸しください。よろしくお願いします。

  • 固定長データのテキストファイルのスペースについて

    固定長データのテキストファイルをExcelで読み込むと、スペース部分が前詰めされてしまいます。 スペースもそのままカラムとして読み込む方法はありませんでしょうか。 例えば次のような固定長データがあるとします; No.  項目名   タイプ   桁数 1    コード    文字    6 2    状態    文字    10 テキストファイルで開くと下記のような表示です(以下、便宜上スペースを”_”で表します); data011________1 data02_________1 data03____1_____ これをExcelにて固定長フィールドのデータとして読み込む際、 フィールドの区切り位置として6カラム目と16カラム目に矢印を置き 全てのフィールドを文字列として読みこむとExcelでは下記のように表示されます;       A列   B列    1行目  data01 1________1 2行目  data02 1 3行目  data03 1 ここで、B2セルとB3セルがそれぞれ _________1 ____1_____ とスペースを保持したままの形で読み込む方法はありませんでしょうか。 手動でもVBでもかまいません。ご教示頂ければ幸いです。

  • Excelファイルから固定長データの作り方について

    次のエクセルのデータを   番号  金額               ← 空白行が入ります。   1001 300               ← 空白行が入ります。   1002 400               ← 空白行が入ります。   1005 800               ← 空白行が入ります。   1013  1200 下記のように固定長のデータに変換したいのですが 2 00000300 0010010001 2 00000400 0010020002 2 00000800 0010050003 2 00001200 0010130004 「2」(固定)、「 」(スペース5個))、金額(8桁)、「」(スペース1個)、番号(6桁)、連番(4桁) どのようにしたらいいのでしょうか? VBを使えばいいとは思うのですが、よくわかりません。

  • C言語で16進数をテキスト出力したい。

    お世話になります。 件名の内容で、参考になるサイトや手法などをご教授願います。 【件名】C言語で16進数をテキスト出力したい。 【環境】OS:WindowsXPsp2 コンパイラ:borlandC 【詳細】 現在、C言語で以下の手順で処理を行うプログラムを作成しております。 手順1:ASCIIコードで記載されたテキストをUTF8コードに変換 手順2:UTF8に変換された1行目の文字列を16進数コードフォーマットをファイル名にして保存 手順2の16進コードフォーマットのファイル名にして保存する作業で fprintf(buff,"%x",UF8); //"buff"保存ファイル名、"UTF8"1行目文字列 を用いて行えるかと思ったのですが、どうやら直接16進数の名称を吐き出すことが不可能なようで、どのように行ったらいいか皆目検討がついておりません。 そこで大変恐縮ですが、参考になる手法や、情報がありますサイト等をお教え頂けると幸甚です。 よろしくお願いいたします。

  • テキストファイルについて

    あるデータがカンマ区切りなのか、タブ区切りなのか、スペース区切りなのかはテキストファイルにしてメモ帳で開いて確認するしかないんでしょうか? 宜しくお願いします。

  • エクセルに二つのテキストファイルをインポートしたい

    エクセルのsheet1の1行目にタイトルがあります。 ボタンのクリックイベントで、テキストファイル2つをインポートしたいのですが。 ・テキストファイルの名前は、固定ではありません ・テキストファイルの保存先は、デスクトップで、ファイルの選択は自分でしたい ・テキストファイルの一行目は、タイトル行なので、二行目以降をインポートしたい 行数は固定ではありません ・タブ区切りです 複数選択はできなく、1ファイルでタイトル行も含めるのであれば下記コードできたのですが。 どなたか、ご教示いただけますでしょうか・・・・ よろしくお願いいたします。 ----------------------------------------------------- Sub ReadTextFile() 'タブ区切りファイルを全て文字列として読み込む Dim FileName As String Dim i As Long Dim Cnt As Long Dim Buf As Variant Dim FileNo As Integer Dim SplitString As Variant 'ファイルダイアログを表示 FileName = Application.GetOpenFilename("テキストファイル,*.txt") If FileName <> "False" Then '全セル選択して書式を文字列にセットする Cells.Select Selection.NumberFormatLocal = "@" Cells(1, 6).Select '空いているファイル番号を取得 FileNo = FreeFile() Buf = Space(FileLen(FileName)) 'ファイルを開いてbufに1行読み込み ' → タブで配列に分割 ' → セルに書き出し Open FileName For Input As #FileNo Do Until EOF(FileNo) Line Input #FileNo, Buf Cnt = Cnt + 1 SplitString = Split(Buf, vbTab) For i = 0 To UBound(SplitString) Cells(Cnt, i + 1) = SplitString(i) Next i Loop Close #FileNo Else End If End Sub -----------------------------------------------------

  • アクセス2010でのファイル保存方法

    アクセス2010で、UTF8形式のテキストを開き、レコードごとにデータを 抽出する際でのご質問がございます。 指定された県の郵便番号を、レコードを抽出して、ファイルで保存する際、テキスト型文字コードUTF8に指定して保存したのですが、レコード内のフィールド文字列でスペースを含んだ半角文字14桁と全角文字8桁の混合文字列が、保存後、前半部分の半角文字のスペースがなくなってしまいます。 下記のような例がイメージとなります。 例 ァァァ           亜亜亜亜亜亜亜亜    ↓   ァァァ 亜亜亜亜亜亜亜亜  (半角領域のスペースが1桁しかなくなってしまう) のようになってしまうのですが なにか良い保存方法はありますでしょうか? どうぞよろしくお願いします。

  • テキストファイルからの抽出

    VBAでもコマンドプロンプトでもいいのですが、1000行くらいあるテキストファイルを読み込んで、キーワード「タイムアウト」を含む行の1つ手前の行の文字列を抽出、それらを1つのファイルにまとめて出力させたいのです。 VBAで自分なりにやってみたのが http://detail.chiebukuro.yahoo.co.jp/qa/question_detail/q12142881517 の最後の回答にあるマクロに手を少し加えて「タイムアウト」のある行番号をテキストファイルに出力し、その出力ファイルを読み込んで、一つ手前の行番号のリストを作ることまではできました。 ですが、どうやってそのリストから行番号を指定して、元のファイルからタイムアウトを含む行の1つ手前の行を抽出し、1つのファイルにまとめて出力させられるのかが分かりません。 後Powershellはまだ勉強途中なのですが、こっちでならできますか? アドバイスをお願いします。

専門家に質問してみよう