ファイルの中身をすべてメモリに保存する方法 – プログラミング – Home

ファイルの中身をすべてメモリに保存する...
 
通知
すべてクリア

ファイルの中身をすべてメモリに保存する方法


もも
 もも
(@もも)
ゲスト
結合: 23年前
投稿: 36
Topic starter  

こんにちわ。

CFileのOpenでファイルを開いて、
そのファイルの中身をすべて文字列として保存しようと思っています。
Openはうまくいくのですが、
なぜかReadでファイルの中身が取得できません。

CFile cfIni;
char buff[512];
if(cfIni.Open(m_strInifilePath,
CFile::modeReadWrite | CFile::typeBinary |
     CFile::shareExclusive) == TRUE)
{
 cfIni.SeekToBegin();
 cfIni.Read(buff,512);
}

ファイルの中身を文字列としてうまく取得する方法はないでしょうか?

よろしくお願いします。


引用解決済
トピックタグ
Blue
 Blue
(@Blue)
ゲスト
結合: 20年前
投稿: 1467
 

どのように取得できた出来ないをはんだんしていますか?
バイナリモードで読み込んでいますので当然途中に’\0’が入ることもあります。

それと気になった点

>if(cfIni.Open(m_strInifilePath,
> CFile::modeReadWrite | CFile::typeBinary |
>     CFile::shareExclusive) == TRUE)

CFile::typeBinaryはMSDNに派生クラスで使いますとあります。
CFileで開けば必ずバイナリで開いていますので指定する必要はありません。

BOOL型の戻り値に対して == TRUE とするのはよくありません。
詳しくは
(int型変数の評価)
http://rararahp.cool.ne.jp/cgi-bin/lng/vc/vclng.cgi?print+200505/05050084.txt
で議論になっているので参考に。

それと、一応try~catchで囲んでCFileExceptionを捕まえるような処理を入れたほうが
無難だと思います。

>ファイルの中身を文字列として
ということならば CFileの派生クラスのCStdioFileを使われてはどうでしょうか?


返信引用
reshia
 reshia
(@reshia)
ゲスト
結合: 20年前
投稿: 117
 

if( cfIni.Open(....) == TRUE )
これがダメです。
CFile::Openの仕様では、ファイルのオープンに失敗すると「0」を返し
成功した場合、「0以外」を返します。TRUEを返すわけではありませんので、
「 cfIni.Open(....) == TRUE 」は成り立たないので
「cfIni.Read(buff,512);」は呼ばれていない可能性があります。

本当に、このReadが呼ばれているのかを確かめてください。

##テストした方法を示します。VC2003です。
プロジェクト:「Win32コンソールプロジェクト」
設定:サポートの追加の項で「MFC」にチェック
以下のコードを追加
//----------------------------------------
// TODO: アプリケーションの動作を記述するコードをここに挿入してください。
CFile cfIni;
char buff[512];
int readsize;
if(cfIni.Open(m_strInifilePath, CFile::modeReadWrite | CFile::typeBinary |
CFile::shareExclusive) == TRUE)
{
cfIni.SeekToBegin();
cfIni.Read(buff,512);
_tprintf(%s\n, buff);
}
//----------------------------------------
として確かめました。

ファイルサイズが512バイト以下では、上手く動作しませんのであしからず。
あと、この場合「cfIni.SeekToBegin();」はなくても動きます。


返信引用
Blue
 Blue
(@Blue)
ゲスト
結合: 20年前
投稿: 1467
 

>ファイルサイズが512バイト以下では、上手く動作しませんのであしからず。
はどんな時、何がうまくいきませんでした?
(そんなことないと思うのですが・・・VC7からは動かないのかなぁ。。。)

一応全てのExceptionをcatchできるようにコンストラクタでオープンしてみたのを
載せておきます。
# ファイル名はテキトーですが。

try
{
CFile fileInput( test.txt, CFile::modeReadWrite |
CFile::shareExclusive );
TCHAR szBuff[ 512 ] = { 0 };
fileInput.Read( szBuff, sizeof( szBuff ) );
cout << szBuff << endl;
fileInput.Close();
}
catch ( CFileException* ex )
{
TCHAR szCause[ 255 ];
ex->GetErrorMessage( szCause, sizeof( szCause ) );
ex->Delete();
cerr << szCause << endl;
}

ちなみに、私の環境はWinXp SP2のVC6 SP6 です。


返信引用
reshia
 reshia
(@reshia)
ゲスト
結合: 20年前
投稿: 117
 

>どんな時、何がうまくいきませんでした?
どうやら、CFile::Readは、指定されたサイズ分きっちり読み込んでくれますが、
その後にナル文字は入れてくれません。
なので、printfでの出力には、いつもの「フフフフフ」が出てきてしまいます。
std::coutでも同じ状態です。

上手くやろうと思うと、
CFile::Readの返り値が「バッファに転送されたバイト数」ですから、
(ちょっと上のプログラムに残骸が残ってしまっていたのですが)
char buff[513];
int readsize = cfIni.Read(buff,512);
などとして、
buff[readsize] = '\0';
とする必要があるみたいです。


返信引用
reshia
 reshia
(@reshia)
ゲスト
結合: 20年前
投稿: 117
 

あ、すみません。
だから、512バイト以下だろうが以上だろうが、
最初に私が提示したプログラムはうまくいきません。


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

stream系を使った方が楽じゃないすか?

/*
* readmyself.cpp
*/
#include <fstream>
#include <sstream>
#include <iostream>

int main() {
std::ifstream in(readmyself.cpp);
std::ostringstream out;
out << in.rdbuf(); // 一気に全部読む
std::cout << '[' << out.str() << ']';
return 0;
}


返信引用

返信する

投稿者名

投稿者メールアドレス

タイトル *

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