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

A 回答 (3件)

 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;
}

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

getlineという関数もあるのですね。
初めて知りました。

回答を読む時間しかなくて、お礼が遅くなってしまってました。
これからはこまめに見るようにしたいと思います。

回答ありがとうございました。

お礼日時:2001/07/05 14:27

L_E_Dさんも書かれていますがfgets等行単位で読み込む関数を使えば可能です。


しかしどうも文面から察するにロジックの組み立てに慣れていないのではないでしょうか?
少なくともファイルがオープンできていれば後はfor文等で簡単に出来ます。(カウンターで行数をカウントすれば良いですよね)
頭から4行目までは読み出すだけで捨てておいて5行目からEOFが出るまで読み込んでいけば最初の例はクリアできますよね。
2番目の例も10行目から20行目までの読み込みが終わったらループを抜ければ良いだけです。

それともひょっとしたらUnixのコマンド(tail等)で同様のことが一発で出来るのでUnix環境ならC++でも出来ると誤解されていますか?
環境が変わってもロジック的なところは共通ですよ。
    • good
    • 0
この回答へのお礼

必要な行だけを使えばよかったのですね。
そこまで考え付きませんでした。
なんか便利な関数があったりするのかなあって思ったので質問したのですが・・・。
回答ありがとうございました。

お礼日時:2001/07/05 14:24

fgetsのループで出来ます。

詳細はヘルプを見て下さい。
    • good
    • 0
この回答へのお礼

ありがとうございました。
なんとか解決しました。

お礼日時:2001/07/05 14:20

お探しの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() 関数で取得可能です。
 ※なおバイナリモードでオープンして下さ...続きを読む

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

テキストには -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関数で読み込んでもできますが、書式とデータがあっていないと上手くいかないので注意してください。

QC言語で複数列のデータを1列のみ読み込みたい

行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);

行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",&...続きを読む

Aベストアンサー

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

 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

Qテキストファイルの行数を取得する方法(C言語

C言語でテキストファイルのトータル行数を取得する関数又はその方法を教えてほしいのですが。

宜しくお願いします。

Aベストアンサー

>C言語でテキストファイルのトータル行数を取得する関数又はその方法を教えてほしいのですが。

 3つ前の質問 http://okwave.jp/qa5129642.html 質問文中のソース冒頭 line2++; 部分(下に修正したもの掲載)で、

・テキストファイルの行数を、ファイルの頭から1行ずつ「読み捨て」て、それをファイル終端まで繰り返すことで数えています。

 ここでは、「全体として、どの位メモリを確保したらいいか」という動機から、超みっともない?こと(読み捨て、1ファイルを2度オープン)をしています。
  (本人には、http://okwave.jp/qa5114580.html の No.3 で指摘済み)
 1行ずつ読み込みながら、1行分のメモリを追加確保していくのが普通だと思うのですが・・。

・エディタでファイルを開けば判ることを、わざわさプログラムにする理由はなく、(質問文には現れない)主目的との「兼ね合い」でご質問された、と思います。
・「何々したいから、プログラムの冒頭で、ファイルのトータル行数を取得しておきたい」の「何々」部分を明らかにすれば、「兼ね合い」を解消する技法について「回答」が得られるかもしれません。

もし、上の質問者様と同様な動機でしたら、少なくとも、「エディタでファイルを開き、行数を確認」し、プログラム実行時にコマンドラインで、argv[ 2 ] に行数が入るようにして下さい。
超みっともない「読み捨て、1ファイルを2度オープン」は不要となります。

プログラムでは、line2 = atoi( argv[ 2 ] ); とすることで、行数を得ることができます(ファイル名は、argv[ 1 ] で)
----------------------------------------------
直球回答

int line2 = 0;
char buf[ 1024 ]; // 最大レコード長より大きいこと
FILE *fp;

if( NULL == ( fp = fopen( argv[ 1 ], "r" ) ) ){

 printf( "%s が開けません\n", argv[ 1 ] );

 return( -1 );
}
while( NULL != fgets( buf, 1024, fp ) ){

 line2++;
}
fclose( fp );

>C言語でテキストファイルのトータル行数を取得する関数又はその方法を教えてほしいのですが。

 3つ前の質問 http://okwave.jp/qa5129642.html 質問文中のソース冒頭 line2++; 部分(下に修正したもの掲載)で、

・テキストファイルの行数を、ファイルの頭から1行ずつ「読み捨て」て、それをファイル終端まで繰り返すことで数えています。

 ここでは、「全体として、どの位メモリを確保したらいいか」という動機から、超みっともない?こと(読み捨て、1ファイルを2度オープン)をしています。...続きを読む

QLNK2019: 未解決の外部シンボルのエラーが出る

Microsoft Visual Studio 2008
Version 9.0.21022.8 RTM
Microsoft .NET Framework
Version 3.5 SP1
----------------------------------------------------------------
新しいプリジェクト→Win32 コンソール アプリケーション(ソリューションのディレクトリを作成 チェック外す)→Windows アプリケーション(空のプロジェクト チェック外す)
----------------------------------------------------------------
 プログラム

 mymain.cpp
#include "myhelper.h"
#include "mymain.h"

//自キャラのデータ
Point2D g_jikipos = {40, 400};//自キャラの座標

//画像ハンドル
int g_jikiimage[11];

//色々なファイルの読み込み
int LoadFiles(){
//画像ファイル読み込み
if(LoadDivGraph("media\\player01.bmp",
11,11,1,64,64,g_jikiimage) == -1) return -1;

return 1;
}


 mymain.h
//他から呼び出させるMyMainの関数
void MyMain();
int LoadFiles();


 myhelper.h(サンプルなので打ちミスはない)
#include "DxLib.h"
#include <limits.h>
#include <math.h>

//構造体宣言
//座標またはベクトルを記録する構造体
struct Vector{
float x,y;
};
typedef Vector Point2D;
//線を記録する構造体
struct Line2D{
Point2D startpos, endpos;
float katamuki;//傾きをラジアン値で記録
Vector speed;//移動している場合は速度をセット
};
//球体を記録する構造体
struct Ball2D{
Point2D position;
float hankei;//半径
};
//四角形を記録する構造体
struct Rect2D{
Point2D lefttop;
Point2D rightbottom;
float width;
float height;
};


//ライブラリ関数
Point2D PosInView(Point2D in);
int XInView(float inx);
int YInView(float iny);
void ScrollToLeft(float jikiposx);
void ScrollToRight(float jikiposx);
void ScrollToUp(float jikiposy);
void ScrollToDown(float jikiposy);
void DrawLineInView(float x1, float y1, float x2, float y2, int Color, int Thickness);
void DrawCircleInView(float x, float y, float r, int Color, int FillFlag);
void DrawAnimation(float x, float y, double ExtRate, double Angle,int TurnFlag,
int *imgarray, int allframe, float fps);
//ベクトル関数
Vector CreateVector(Vector in, float veclen);
Vector AddVector(Vector v1, Vector v2);
Vector SubVector(Vector v1, Vector v2);
Vector AddVectorInFrameTime(Vector pos, Vector speed);
Vector AddVectorInFrameTime2(Vector pos, Vector speed, Vector accel);
Vector Normalize(Vector in);
Vector RotateVector(Vector in, float radian);
float VectorLengthSquare(Vector in);
float DotProduct(Vector v1, Vector v2);
float CrossProduct(Vector v1, Vector v2);
void SetLine2DKatamuki(Line2D *in);
void DrawLine2D(Line2D in, int Color, int Thickness);
void DrawBall2D(Ball2D in, int Color, int Fill);
//当たり判定関数
bool HitTestLineAndBall(Line2D linein, Ball2D ballin);
bool IsPointAtLineFace(Line2D linein, Point2D ptin);
bool HitTestLineAndLine(Line2D line1, Line2D line2);
bool HitTestBallAndBall(Ball2D a, Ball2D b);
bool HitTestPointAndBox(Rect2D rect, Point2D pt);
//タイマー関数
void SetSimpleTimer(int idx, int time);
int GetPassedTime(int idx);


//グローバル変数
extern float g_frametime;
extern Rect2D g_framerect;//画面領域(当たり判定)
extern Point2D g_current_field_pos;//現在の左上座標
extern Rect2D g_stagesize;//ステージサイズ

//定数宣言
const float ZEROVALUE = 1e-10f;
const float PIE = 3.1415926f;
const int SCROLL_LIMIT = 200;
----------------------------------------------------------------
 エラー内容
1>myhelper.obj : error LNK2019: 未解決の外部シンボル "void __cdecl MyMain(void)" (?MyMain@@YAXXZ) が関数 _WinMain@16 で参照されました
1>C:\Documents and Settings\Owner\My Documents\Visual Studio 2008\Projects\my\Debug\my.exe : fatal error LNK1120: 外部参照 1 が未解決です
1>my - エラー 2、警告 0
ビルド: 0 正常終了、1 失敗、0 更新不要、0 スキップ
----------------------------------------------------------------
画像を貼り付けときます
(見えにくい場合→http://www.dotup.org/uploda/www.dotup.org154142.jpg.html)
初心者なのでわかりやすくお願いします

Microsoft Visual Studio 2008
Version 9.0.21022.8 RTM
Microsoft .NET Framework
Version 3.5 SP1
----------------------------------------------------------------
新しいプリジェクト→Win32 コンソール アプリケーション(ソリューションのディレクトリを作成 チェック外す)→Windows アプリケーション(空のプロジェクト チェック外す)
----------------------------------------------------------------
 プログラム

 mymain.cpp
#include "myhelper.h"
#include "mymain.h"

//自...続きを読む

Aベストアンサー

ファイル構成から推測するに
mymain.cpp というファイルに
void MyMain(void) {
// ここに処理を書く
}
という関数が必要なようです。

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ファイルの中身検索と表示

Cでの作成についてなんですが、
fopenでテキストファイルを開き、テキストの中身の
特定文字が含まれている行を新に作ったファイルの中に
書き込みたいんですが、テキストの中身の検索と
抽出方法がいろいろ試してみましたがわかりません。
よろしくお願いします。

Aベストアンサー

★文字列の検索関数を使えば良い。
・テキストの中身の検索は、行単位で文字列を取得(fgets)してから、この文字列内に
 検索文字列の有無をチェックします。この有無は文字列から文字列を検索する関数
 『strstr』関数を使うのが便利です。また、文字列から1文字の検索を行う場合は
 『strchr』関数を使います。質問では、特定の文字が含まれている行となっていますが
・検索するのは1文字、文字群、文字列のどれですか?
 これによっていろいろと代わりますよ。処理が…。
・とりあえず文字列から特定の文字列を含まれた行を抽出するサンプルを下に載せます。

サンプル:
char buff[ 256 ];
char *find = "検索文字列";
FILE *fp; ←読み込み用
FILE *fo; ←抽出用

省略(fopen×2つ)

while ( fgets(buff,sizeof(buff),fp) != NULL ){
 if ( strstr(buff,find) != NULL ){
  fputs( buff, fo );
 }
}

省略(fclose×2つ)

解説:
・上記のサンプルでは、行単位でテキストの中身を取得して、この文字列から検索文字列(find)が
 含まれるか『strstr()』関数でチェックしています。見つかると『NULL』以外を返します。
・そして、見つかったらば行単位で『fputs』関数で出力しています。
 これで見つかった行だけが、新たに作ったファイルに書き込まれていきます。→抽出です。
・また『strstr()』関数の部分を
 『if ( strchr(buff,'a') != NULL ){ … }』とすると『a』の文字が含まれる行のみを抽出します。
 『if ( strspn(buff,"+-*/") != 0 ){ … }』とすると『+-*/』の文字群が含まれる行のみを抽出します。
 検索する文字とは、1文字、文字群、文字列のどれですか?
・以上。おわり。→上記のを参考にして下さい。

参考URL:http://www9.plala.or.jp/sgwr-t/lib/strspn.html,http://www9.plala.or.jp/sgwr-t/c/sec17.html

★文字列の検索関数を使えば良い。
・テキストの中身の検索は、行単位で文字列を取得(fgets)してから、この文字列内に
 検索文字列の有無をチェックします。この有無は文字列から文字列を検索する関数
 『strstr』関数を使うのが便利です。また、文字列から1文字の検索を行う場合は
 『strchr』関数を使います。質問では、特定の文字が含まれている行となっていますが
・検索するのは1文字、文字群、文字列のどれですか?
 これによっていろいろと代わりますよ。処理が…。
・とりあえず文字列から特定...続きを読む

Qファイルやディレクトリの存在確認を行う方法

ファイルをオープンするのはfopenでOKですが、ファイルやディレクトリの存在確認を行う方法が知りたいです。

何か組み合わせて作るものなのでしょうか?
perlとか便利な演算子があるのですが、C/C++って器用ではないですね。
これは処理系?依存の内容ですか?

私の環境は VC6, VC2005 Windows2000です。

Aベストアンサー

int access(const char* path, int mode);
int stat(const char* path, struct stat* sb);

かな?
MSDN を引くと _access_s() を使えとか書いてあるけど。


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

人気Q&Aランキング