プロが教える店舗&オフィスのセキュリティ対策術

ファイル内の文字を一部だけ置き換えたいのですが、どんなソースを使えばいいでしょうか。
参考にしたいので、よろしくお願いします。

ABCDEFGHI

のEFだけをそれぞれ+にする。
と言うものです。

A 回答 (3件)

ABCDEFGHIという文字列が入っていることが保証されているのであれば...



#include <cstdio>

int main()
{
 std::FILE* stream = std::fopen("file.txt", "rb+");
 std::fseek(stream, 4, SEEK_SET);
 std::fwrite("++", 1, 2, stream);
}

とすればよいのでは?

ファイル名は仮に file.txt としています。
また、エラーチェックは省略しています。

...と思って投稿しかけたのですが、+は全角ですね。
これだとその部分だけの置き換えでは済まなくなります。
    • good
    • 0

テキストエディタ(メモ帳)等で、編集すればよいかと思いますが。

    • good
    • 0

こんにちは。



テキストファイル内の"EF"を全て"++"に置換するという解釈でサンプルを
作ってみました。(C++で作成してあります。)
宜しければ試してみて下さい。
※ご使用の環境でビルド&実行が上手くいかなかった場合はすみません。

入力&出力ファイルは固定のファイル名としています。
 ・入力ファイル名: "test.txt"
 ・一時ファイル名: "temp.txt"  (置換後のテキストを一時保存するファイル)
 ・BAKファイル名: "test.bak"  (置換した場合のバックアップファイル)

■サンプルプログラム
注)インデントのため全角スペースを入れています。
  コピペの際は半角スペースorタブに置換して下さい。

/////↓ここから///////////////
/*
* テキストファイル上の文字列置換(サンプル)
*/
#include <iostream>
#include <fstream>
#include <string>
#include <stdio.h>
#include <errno.h>
using namespace std;

int main()
{
  int line;      //行カウンタ
  int rcnt;      //置換カウンタ
  int ferr;      //ファイルエラーフラグ
  char sLine[256];  //1行読込みバッファ
  ifstream finp;    //入力ファイルストリーム
  ofstream fout;    //出力ファイルストリーム
  string strWk1;    //文字列ワーク
  string strWk2;    //文字列ワーク
  string strWk3;    //文字列ワーク
  string::size_type idx;  //文字位置インデックス

  //== ファイル名
  const char szInpFn[] = { "test.txt" };  //入力ファイル
  const char szTmpFn[] = { "temp.txt" };  //一時ファイル
  const char szBakFn[] = { "test.bak" };  //BAKファイル

  //== 入力ファイルオープン
  finp.open( szInpFn );
  if( !finp ){
    cout << "Cannot open file. (inp)" << endl;
    return 1;
  }

  //== 一時ファイルオープン
  fout.open( szTmpFn );
  if( !fout ){
    cout << "Cannot open file. (tmp)" << endl;
    finp.close();
    return 1;
  }

  //== 文字列置換しながらファイルをコピー
  line = 0;  //行カウンタクリア
  rcnt = 0;  //置換カウンタクリア
  ferr = 0;  //ファイルエラーフラグクリア
  do {
    //入力ファイルより1行読込み
    finp.getline( sLine, sizeof(sLine) );
    if( !finp.eof() && (finp.bad() || finp.fail()) ){
      //エラーなら読込み終了
      ferr = 1;  //ファイルエラーフラグON
      break;
    }
    if( finp.eof() ) break;  //EOFなら読込み終了

    //文字列置換
    strWk1 = sLine;    //入力文字列
    strWk2 = "EF";    //検索文字列
    strWk3 = "++";  //置換文字列
    do {        //1行分の全置換
      idx = strWk1.find( strWk2 );    //検索
      if( idx == string::npos ) break;  //なければループ脱出
      strWk1.replace( idx, strWk2.size(), strWk3 );  //置換
      rcnt++;      //置換カウンタUP
    } while(1);

    //一時ファイルに1行書込み(置換後の文字列)
    fout << strWk1 << "\n";
    line++;  //行カウンタUP

    //==debug
    cout << "line no\t: " << line << endl;
    cout << "inp str\t: " << sLine << endl;
    cout << "out str\t: " << strWk1 << endl;
    //==debug

  } while(1);

  //==debug
  cout << "total lines\t: " << line << endl;
  cout << "replace count\t: " << rcnt << endl;
  //==debug

  //== ファイルクローズ
  finp.close();
  fout.close();

  //== ファイルエラーなら終了
  if( ferr ){
    cout << "file read error. (inp)" << endl;
    return 2;
  }

  //== 置換無しなら一時ファイルを削除して終了
  if( rcnt < 1 ){
    remove( szTmpFn );
    return 0;
  }

  //== ファイル名変更(1):入力ファイル⇒BAKファイル
  if( remove( szBakFn ) == -1 ){  //既存のBAKファイルを削除
    if( errno == EACCES ){    //読出し専用だったらエラーで終了
      cout << "file remove error. (bak)" << endl;
      return 3;
    }
  }
  if( rename( szInpFn, szBakFn ) != 0 ){  //リネーム(入力⇒BAK)
    cout << "file rename error. (inp -> bak)" << endl;
    return 4;
  }

  //== ファイル名変更(2):一時ファイル⇒入力ファイル
  if( rename( szTmpFn, szInpFn ) != 0 ){  //リネーム(一時⇒入力)
    cout << "file rename error. (tmp -> inp)" << endl;
    return 4;
  }

  return 0;
}
/////↑ここまで///////////////

<入力ファイル:置換前>
ABCDEFGHI-EF-
EF012ABCDEF
ABCDEF0123
0123456789

<実行結果>
line no : 1
inp str : ABCDEFGHI-EF-
out str : ABCD++GHI-++-
line no : 2
inp str : EF012ABCDEF
out str : ++012ABCD++
line no : 3
inp str : ABCDEF0123
out str : ABCD++0123
line no : 4
inp str : 0123456789
out str : 0123456789
total lines     : 4
replace count  : 5

<入力ファイル:置換後>
ABCD++GHI-++-
++012ABCD++
ABCD++0123
0123456789

以上です。参考になれば幸いです。
    • good
    • 0
この回答へのお礼

こんなに長いプログラミングを
ありがとうございました!!!

是非参考にさしてもらいます!

お礼日時:2009/10/21 17:12

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!