私は何を間違っていますか?
ファイルから読み取って、データを文字列構造自体に入れようとして上書きしようとしていますが、これは明らかに間違っています。
http://www.cplusplus.com/reference/iostream/istream/read/で確認できるように、使用std::string
した型が間違っていましchar *
たreinterpret_cast
。
C++ ヒント: C++ でa を使用することreinterpret_cast
は、(ほぼ) 常に何か間違ったことをしている兆候です。
ファイルの読み取りがなぜ複雑なのか?
昔は、ファイルを読むのは簡単でした。一部の Basic ライクな言語では、関数 を使用していましLOAD
た。、あなたはあなたのファイルを持っていました。では、なぜ今それができないのでしょうか。
ファイルの中身がわからないからです。
- それは文字列かもしれません。
- これは、メモリからダンプされた生データを含むシリアル化された構造体の配列である可能性があります。
- ライブ ストリーム、つまり継続的に追加されるファイル (ログ ファイル、stdin など) の場合もあります。
- データを単語ごとに読み取ることができます
- ...または行ごと...
- または、ファイルが大きすぎて文字列に収まらないため、部分的に読み取る必要があります。
- 等..
より一般的な解決策は、ファイル (したがって、C++ では fstream) を読み取り、関数 get ( http://www.cplusplus.com/reference/iostream/istream/get/を参照)を使用してバイト単位で読み取り、実行することです。期待する型に変換する操作を自分で行い、EOF で停止します。
std::isteam
インターフェイスには、さまざまな方法でファイルを読み取るために必要なすべての機能があり ( http://www.cplusplus.com/reference/iostream/istream/を参照)、さらに、追加の非メンバー関数がありますstd::string
。区切り文字が見つかるまでファイルを読み取ります (通常は "\n" ですが、何でもかまいません。 http://www.cplusplus.com/reference/string/getline/を参照してください)
しかし、私は「ロード」機能が欲しいstd::string
!!!
わかったよ。
ファイルに入れるのは の内容であると仮定しますがstd::string
、C スタイルの文字列との互換性を維持します。つまり、\0
文字は文字列の終わりを示します (そうでない場合は、到達するまでファイルをロードする必要があります)。 EOF)。
そして、関数が戻ったら、ファイルの内容全体を完全にロードする必要があると仮定しloadFile
ます。
したがって、ここにloadFile
関数があります:
#include <iostream>
#include <fstream>
#include <string>
bool loadFile(const std::string & p_name, std::string & p_content)
{
// We create the file object, saying I want to read it
std::fstream file(p_name.c_str(), std::fstream::in) ;
// We verify if the file was successfully opened
if(file.is_open())
{
// We use the standard getline function to read the file into
// a std::string, stoping only at "\0"
std::getline(file, p_content, '\0') ;
// We return the success of the operation
return ! file.bad() ;
}
// The file was not successfully opened, so returning false
return false ;
}
C++11 対応のコンパイラを使用している場合は、このオーバーロードされた関数を追加できます。コストはかかりません(C++03 では、最適化を行わないと、一時オブジェクトのコストがかかる可能性があります)。
std::string loadFile(const std::string & p_name)
{
std::string content ;
loadFile(p_name, content) ;
return content ;
}
さて、完全を期すために、対応する関数を書きましたsaveFile
:
bool saveFile(const std::string & p_name, const std::string & p_content)
{
std::fstream file(p_name.c_str(), std::fstream::out) ;
if(file.is_open())
{
file.write(p_content.c_str(), p_content.length()) ;
return ! file.bad() ;
}
return false ;
}
そして、これらの機能をテストするために使用した「メイン」は次のとおりです。
int main()
{
const std::string name(".//myFile.txt") ;
const std::string content("AAA BBB CCC\nDDD EEE FFF\n\n") ;
{
const bool success = saveFile(name, content) ;
std::cout << "saveFile(\"" << name << "\", \"" << content << "\")\n\n"
<< "result is: " << success << "\n" ;
}
{
std::string myContent ;
const bool success = loadFile(name, myContent) ;
std::cout << "loadFile(\"" << name << "\", \"" << content << "\")\n\n"
<< "result is: " << success << "\n"
<< "content is: [" << myContent << "]\n"
<< "content ok is: " << (myContent == content)<< "\n" ;
}
}
もっと?
それ以上のことをしたい場合は、http: //www.cplusplus.com/reference/iostream/ で C++ IOStreams ライブラリ API を調べる必要があります。