• ベストアンサー

c言語 ファイルの読み込み位置

ファイルのアクセス位置を最後から7行目に移動させるプログラムを作っています。 \nを数えることで行数を数えているのですが、以下の処理、間違えていますか? コンパイルしてもできていないので間違えていることは明白なのですが、どこが違うかわかりません。 誰か、力になってください! fseek(fp, -1, SEEK_END);/*読込位置最後にする */ while(!fseek(fp, -2, SEEK_CUR))/*逆順読込ループ*/ {   if(getc(fp)=='\n')  {cnt++;}  if(cnt == 7)  {break;} }

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

  • ベストアンサー
  • yasuch
  • ベストアンサー率41% (27/65)
回答No.5

こんな感じはどうでしょうか。 FILE *fp; char c; int cnt=0; int cr_lf=0; fp = fopen("hoge.txt", "r"); fseek(fp, -1L, SEEK_END); do { c=getc(fp); if(cr_lf==0 && (c==0x0D || c==0x0A)){ cnt++; cr_lf=1; } else cr_lf=0; if(cnt==7) break; } while(fseek(fp, -2L, SEEK_CUR)==0); fclose(fp);

その他の回答 (4)

  • jacta
  • ベストアンサー率26% (845/3158)
回答No.4

テキストストリームの場合、fseek関数はSEEK_CURでもSEEK_ENDでもオフセットには0しか指定できません。 というのも、ファイルに格納されている一文字と、プログラムから読み込んだときの一文字が、(文字数も値も)必ずしも対応しないからです。そのため、前から読まないと辻褄が合わなくなります。 典型的なものとしては改行文字で、例えばWindowsでは、ファイルには{ '\r', '\n' }の二文字が格納されているものが、プログラムから読み込むと{ '\n' }一文字になります。fseek関数でオフセットを指定する場合、普通はファイル上でのバイト数を指定する必要があるので、改行文字のところではオフセットを2に数えなければなりません。 他にも、処理系によってはロケール等に応じて更に状態が変化する可能性があります。 バイナリストリームの場合、上記のような問題はありませんが、今度はSEEK_ENDを指定しても、ファイルの終端に位置づけられる保証がなくなります。 つまり、結局は先頭から読んでいく以外に方法はありません。 なお、処理系を特定した場合にはこの限りではありません。

回答No.3

ちょっと見ただけですが、疑問に思った箇所があったのでソースを直してみました。 int r; fseek(fp, 0L, SEEK_END); r = fseek(fp, -1L, SEEK_CUR); while(!r) {   if(getc(fp)=='\n')  {cnt++;}  if(cnt == 7)  {break;}  r = fseek(fp, -2L, SEEK_CUR); } つまり、初回はまだ読んでないのでポインタを一つ戻すだけでよいのでは。

  • seiuchi4
  • ベストアンサー率37% (71/189)
回答No.2

\nは 0Dhと0Ahの複合になりますね。 (CRとLF) ですので、キャラクタで判定するなら、バイナリの0x0Dなどで行ってみては如何でしょうか? 自信はありません。

  • mooti887
  • ベストアンサー率39% (9/23)
回答No.1

変数 cnt を初期化していますか?

関連するQ&A

専門家に質問してみよう