C言語(c++)でお願いします。

Windows上のテキストファイルを、任意の行数を分割するコードを教えてください。
例:100行のa.txt
Seperrate.exe a.txt 4

a_1.txt、a_2.txt、a_3.txt、a_4.txtと
25行のテキストファイルが作成されるような
ものです。

回答の条件
  • URL必須
  • 1人2回まで
  • 登録:2007/06/30 09:08:35
  • 終了:2007/06/30 14:44:40

回答(3件)

id:t_shiono No.1

t_shiono回答回数256ベストアンサー獲得回数222007/06/30 10:30:31

ポイント50pt

ざっとこんな感じでしょうか。

void divide(const std::string& filename, int lineSize)
{
  std::ifstream fin(filename.c_str());

  int fileCount = 1;
  int lineCount = 1;

  std::stringstream stream;
  stream << "a_" << fileCount << ".txt";
  std::ofstream* fout = new std::ofstream(stream.str().c_str());
  while(!fin.eof()){
	char line[256];
	fin.getline(line, sizeof(line));
	(*fout) << line << std::endl;

	++lineCount;
	if (lineCount > lineSize) {
	  fout->close();
	  delete fout;

	  ++fileCount;
	  lineCount = 1;
	  stream.str("");
	  stream << "a_" << fileCount << ".txt";
	  fout = new std::ofstream(stream.str().c_str());
	}
  }

  fout->close();
  delete fout;
}

単純に、getlineで1行ずつ読んでは、ファイルに出力し、規定行数出力すると、出力ファイルを変更しているだけです。

ご希望に添いますか?

http://q.hatena.ne.jp/1183162114(ダミー)

id:Hi-gugu

大変ありがとうございます。

直ぐ、コンパイルが通るようにして頂けたらうれしいです。

2007/06/30 11:20:57
id:Bookmarker No.2

しおり回答回数191ベストアンサー獲得回数342007/06/30 13:07:03

ポイント50pt

こんな感じ。

ただし、

  • エラー処理は省いている
  • ファイル名は ASCII にしか対応していない
  • ちゃんとした動作確認はしていない

ので、適宜修正してください。

参考:

#include <fstream>
#include <string>
#include <vector>
#include <sstream>
#include <iostream>


void put_usage(const std::string &amp;cmd)
{
    std::cerr << "Usage: " << cmd << " in_file sep_num\n";
}

void separate(const std::string &amp;in_pathname, size_t sep_num)
{
    std::string::size_type dot_i = in_pathname.find_last_of('.');
    std::string fname, ext;
    if ( dot_i == std::string::npos ) {
	fname = in_pathname;
    }
    else {
	fname = in_pathname.substr(0, dot_i);
	ext = in_pathname.substr(dot_i);
    }

    std::ifstream in_file(in_pathname.c_str());
    std::string line;
    std::vector<std::string> lines;
    while ( getline(in_file, line) ) {
	lines.push_back(line);
    }
    in_file.close();

    size_t line_num = lines.size() / sep_num;
    if ( line_num * sep_num < lines.size() ) ++line_num;
    for ( size_t i = 0; i < sep_num; ++i ) {
	size_t bj = i * line_num;
	size_t ej;
	if ( line_num <= lines.size() - bj ) {
	    ej = bj + line_num;
	}
	else {
	    ej = lines.size();
	}
	std::ostringstream out_pathname;
	out_pathname << fname << "_" << i + 1 << ext;
	std::ofstream out_file(out_pathname.str().c_str());
	for ( size_t j = bj; j < ej; ++j ) {
	    out_file << lines[j] << "\n";
	}
	out_file.close();
    }
}

int main(int argc, char *argv[])
{
    if ( argc != 3 ) {
	put_usage(argv[0]);
	return 1;
    }

    std::string in_pathname(argv[1]);
    size_t sep_num;
    std::istringstream sep_num_str(argv[2]);
    sep_num_str >> sep_num;

    separate(in_pathname, sep_num);
}

# スーパー pre 記法がバグっているようなので、「&amp;」は「&」に置き換えてください。

id:Mook No.3

Mook回答回数1312ベストアンサー獲得回数3912007/06/30 12:58:24

ポイント10pt

C での実装例です。

#include <stdio.h>
#include <stdlib.h>
#include <stdlib.h>

#define LINE_SIZE 2048

static void fileDiv( char *fileName, int divFileNum );

/*---------------------------------------------------*/
void main( int argc, char *argv[] )
/*---------------------------------------------------*/
{
    /* 引数の確認 */
    if ( argc != 3 ) {
        printf("Separate.exe  fileName fileNum\n");
        return;
    }

    fileDiv( argv[1], atoi( argv[2] ) );
}

/*---------------------------------------------------*/
static void fileDiv( char *fileName, int divFileNum )
/*---------------------------------------------------*/
{
    FILE *ifp, *ofp;
    int iLineNum;
    int oLineNum;
    int fileNum;
    int i;
    char readBuffer[LINE_SIZE];
    char oFileName[1024];
    char *fBaseName;
    char *fExtention = "";

    /* ファイルのオープン */
    if( ( ifp = fopen( fileName, "r" ) ) == NULL ) {
        printf( "%s が開けません\n", fileName );
        return;
    }

    /* ファイルの行数のカウント */
    for( iLineNum=0 ; feof( ifp ) == 0 ; iLineNum++ ) {
        fgets( readBuffer, LINE_SIZE, ifp );
    }

    /* ファイルの先頭に移動 */
    fseek(ifp, 0L, SEEK_SET);

    if ( ( divFileNum < 0 ) || ( divFileNum > iLineNum ) ) {
        printf( "分割数[%d]が不適切です\n", divFileNum );
        return;
    }

    /* ファイル名と拡張子に分割 */
    fBaseName  = fileName;
    for ( i=strlen( fileName ) - 1 ; i>=0 ; --i ) {
        if ( fileName[i] == '.' ) {
            fExtention = &(fileName[i+1]);
            fileName[i] = NULL;
            break;
        }
    }

    /* ファイルを分割 */
    oLineNum=0;
    for( fileNum=1 ; fileNum<=divFileNum ; fileNum++ ) {
        sprintf( oFileName, "%s_%d.%s", fBaseName, fileNum, fExtention );
        ofp = fopen( oFileName, "w" );
        for(  ; oLineNum< ( fileNum * iLineNum / divFileNum ) ; oLineNum++ ) {
            if( fgets( readBuffer, LINE_SIZE, ifp ) == NULL ) break;
            fputs( readBuffer, ofp );
        }
        fclose( ofp );
    }
    fclose( ifp );
}

http://www9.plala.or.jp/sgwr-t/lib/fread.html

  • id:t_shiono
    #include <string>
    #include <fstream>
    #include <sstream>

    を追加すればコンパイル通ると思いますが、いかがでしょうか?

この質問への反応(ブックマークコメント)

「あの人に答えてほしい」「この質問はあの人が答えられそう」というときに、回答リクエストを送ってみてましょう。

これ以上回答リクエストを送信することはできません。制限について

絞り込み :
はてなココの「ともだち」を表示します。
回答リクエストを送信したユーザーはいません