書く側のファイルも読み込み側に合わせたい。 – プログラミング – Home

書く側のファイルも読み込み側に合わせた...
 
通知
すべてクリア

書く側のファイルも読み込み側に合わせたい。

固定ページ 1 / 2

JJ
 JJ
(@JJ)
ゲスト
結合: 22年前
投稿: 8
Topic starter  

 strcpy(filename, fd.cFileName);
fprintf(fo, [%s] , filename);
if ((fp = fopen(filename, rt)) != NULL)
      {
exit(3);
}
というコマンドで、別途、読みこまれたファイルを加工して
WRITE側に出力したいのですが、
そのREAD側のファイルの名前を、*.docとすると、
WRITE側のファイルの名前も、
しれに合わせて、*12.docというようにしたい、
(例えば、READ側のファイルが top.docという名前だとすると、
  加工後のWRITE側のファイルの名前を top12.docというようにしたい)
とすると、WRITE側のファイルの開き方としては、
どうすれば、いいのでしょうか?


引用解決済
トピックタグ
επιστημη
 επιστημη
(@επιστημη)
ゲスト
結合: 22年前
投稿: 1301
 

ファイル全体を一気に取り込んでおくことができるなら、そのまま同名で上書きすればよし。
それが無理ならとりあえず異なる名前で書いてからファイル名をすりかえ。


返信引用
sugar
 sugar
(@sugar)
ゲスト
結合: 24年前
投稿: 448
 

top.docというファイル名から、top12.docという名前を
どうやって作ればよいかを聞かれているようにも解釈できるのですが。

_splitpath()という関数を使うと、パス名やら拡張子やらをバラバラに分解できます。
あとは文字列操作で12をくっつけてあげればよいような。

入力ファイルも出力ファイルも物理的に別々なファイルなら、
プログラムの冒頭で2つのファイルをオープンしておけばいいし・・・

そういうことじゃないのかな?


返信引用
επιστημη
 επιστημη
(@επιστημη)
ゲスト
結合: 22年前
投稿: 1301
 

あ、そういうコトか。失礼。
ならば単に文字列操作だけの問題です。
ファイル名の中で最後に現れる'.'を探し、
その前に12を挿入すればいいのだから。


返信引用
ん
 ん
(@ん)
ゲスト
結合: 23年前
投稿: 106
 

FILE *fp1 ;
FILE *fp2 ;
char buff[256] ; // サイズは適当です。扱う情報にあわせて変更が必要。
char fileName1[256] ;
char fileName2[256] ;
char *p ;

printf(暇つぶしに作ってみました。) ;
printf(サンプルです。コンパイルしてません。ご利用はご自身の責任下でお願いします。);

strcpy( fileName1, top.doc ) ;
strcpy( fileName2, fileName1 ) ;

p = strchr( fileName2, '.' ) ; // 拡張子 .doc 開始部分取得
*p = '\0' ; // top.doc を top にする
strcat( fileName2, 12 ) ; // top を top12 にする
p = strchr( fileName1, '.' ) ; // top.doc の拡張子部分をもってくる
strcat( fileName2, p ) ; // top12 を top12.doc にする

// top.doc オープン処理 /////////////////////////////////////////////////////
fp1 = fopen( fileName1, rt ) ; // top.doc をテキスト読み込み用にオープン
if( fp1 == NULL )
{
return ; // top.doc オープン失敗
}

// top12.doc オープン処理 ///////////////////////////////////////////////////
fp2 = fopen( fileName2, wt ) ; // top12.doc をテキスト書き込み用にオープン
if( fp2 == NULL )
{
return ; // top12.doc オープン失敗
}

// top.doc 参照& top12.doc 書き込み //////////////////////////////////////
while( !feof(fp1) )
{
// 1行取得
if( fgets( buff, 255, fp1 ) == NULL )
{
printf( top.doc 参照失敗 ) ;
break ;
}

// なにか加工するならこの場所で。

if( fputs( buff, fp2 ) == EOF )
{
printf( top12.doc 書き込み失敗 ) ;
break ;
}
}

// top.doc と top12.doc のクローズ処理 ////////////////////////////////////
fclose( fp1 ) ; // top.doc のクローズ
fclose( fp2 ) ; // top12.doc のクローズ

printf(終了です。);


返信引用
JJ
 JJ
(@JJ)
ゲスト
結合: 22年前
投稿: 8
Topic starter  

みなさん
ありがとうございます。

おかげさまで、ファイルは、.docの付くファイルは
全て、スキャンさん、中身も新たに変わったものも出来たのですが、
一つ問題が起きました。

それは、
元のファイルが、XXX.doc
新しいファイルが、XXX12.doc
だから、
一通り既存のXXX.doc系のファイルに対して、スキャンが終わると、
次に、新しく出来たXXX12.doc系のファイルに対してもスキャンに入り、
同じく加工に行き、永久ループに入ります。

既存のXXX.doc系のファイルに対してだけに
この操作を限定させるようなことは出来ないのでしょうか?


返信引用
επιστημη
 επιστημη
(@επιστημη)
ゲスト
結合: 22年前
投稿: 1301
 

書き込みを始める前にファイルの検索だけ先にやっちまっておけばいいんじゃないですか?


返信引用
ひろぴー
 ひろぴー
(@ひろぴー)
ゲスト
結合: 22年前
投稿: 182
 

> 既存のXXX.doc系のファイルに対してだけに
> この操作を限定させるようなことは出来ないのでしょうか?
XXXの部分に数字が入らないのなら文字コードで比較すればよいと思います。
その他ファイル名の桁数が決まっていれば比較は容易に出来ますね。
そういう制約をつけたくなければ、一度つけたXXX12.docのファイル名を保存しておいて
「XXX.doc → XXX12.doc」化する時に一度作成されたかどうかチェックするなどしては
どうでしょうか?


返信引用
ひろぴー
 ひろぴー
(@ひろぴー)
ゲスト
結合: 22年前
投稿: 182
 

あ、επιστημηさんの方式がスマートでよいと思います(ToT)


返信引用
JJ
 JJ
(@JJ)
ゲスト
結合: 22年前
投稿: 8
Topic starter  

さっそくありがとうございます。

ファイルの検索は、
FINDFIRSTFILE

FINDNEXTFILE
の間でfopen、fcloseがうまくかかるか、見ながら
カウントしておいて、
再度、そのカウント回数分、
FINDFIRSTFILE

FINDNEXTFILE
をかけて、加工に行く
ということでいいでしょうか?


返信引用
sugar
 sugar
(@sugar)
ゲスト
結合: 24年前
投稿: 448
 

FINDFIRSTFILE、FINDNEXTFILEで取得したファイル名を
配列などに退避しておけばよろしいかと。
ファイルの加工は、ファイル名さえわかっていれば問題ないはず。
検索ループは1回で十分ですよ。


返信引用
επιστημη
 επιστημη
(@επιστημη)
ゲスト
結合: 22年前
投稿: 1301
 

#include <windows.h>
#include <string>
#include <vector>
#include <iostream>

int main() {

std::vector<std::string> filenames;

// *.doc を(filenamesに)列挙する
WIN32_FIND_DATA find_data;
HANDLE handle = FindFirstFile(*.doc, &find_data);
if ( handle != INVALID_HANDLE_VALUE ) {
do {
if ( !(find_data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) ) {
filenames.push_back(find_data.cFileName);
}
} while ( FindNextFile(handle, &find_data) );
FindClose(handle);
}

// 列挙されたファイルに対し...
for ( std::vector<std::string>::iterator iter = filenames.begin();
iter != filenames.end(); ++iter ) {
std::string read_filename = *iter;
std::string write_filename = read_filename;
// '.'の手前に12を付加する
write_filename.insert(write_filename.rfind('.'),12);
std::cout << read_filename << -> << write_filename << std::endl;
// read_filename を読み、write_filenameに書く
}

return 0;
}


返信引用
サイファ
 サイファ
(@サイファ)
ゲスト
結合: 22年前
投稿: 4
 

vectorのpush_backって限界はないんですかねぇ?


返信引用
επιστημη
 επιστημη
(@επιστημη)
ゲスト
結合: 22年前
投稿: 1301
 

どういった限界でしょうか?


返信引用
PAI
 PAI
(@PAI)
ゲスト
結合: 23年前
投稿: 359
 

>vectorのpush_backって限界はないんですかねぇ?

件数のことであれば size_t がひっくり返るところが限界です。
一般的に2の32乗か、64乗か、

ヒープ容量のことでしたら vectorのpush_back とは無関係です。
他の手段でもそれは限界となります。
一般的にファイル名を扱うぐらいであればまったく問題はありません。
普通のPCであればMAX_PATH長のstring数万件でも扱えます。


返信引用
固定ページ 1 / 2

返信する

投稿者名

投稿者メールアドレス

タイトル *

プレビュー 0リビジョン 保存しました
共有:
タイトルとURLをコピーしました