我做错了什么?
您正在从文件中读取数据并尝试将数据放入字符串结构本身,然后覆盖它,这是完全错误的。
因为可以在 http://www.cplusplus.com/reference/iostream/istream/read/ 进行验证,所以您使用的类型是错误的,并且您知道这一点,因为您必须使用 reinterpret_cast 将 std::string 强制转换为 char *。
C++ 提示:在 C++ 中使用 reinterpret_cast(几乎)总是表明您做错了。
为什么读取文件这么复杂?
很久以前,读取文件很容易。在一些类似 Basic 的语言中,您使用了函数 LOAD,并且瞧!,您有了自己的文件。
那么为什么我们现在不能这样做呢?
因为你不知道文件里有什么。
- 它可能是一个字符串。
- 它可能是一个序列化的结构数组,其中包含从内存中转储的原始数据。
- 它甚至可以是实时流,即连续附加的文件(日志文件、标准输入等)。
- 您可能希望逐字读取数据
- ...或逐行...
- 或者文件太大以至于无法放入字符串中,所以您想分段读取。
- 等等..
更通用的解决方案是读取文件(因此,在 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 的编译器,您可以添加这个重载函数,这将花费您nothing(而在 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" ;
}
}
更多?
如果您想做更多的事情,那么您需要探索 C++ IOStreams 库 API,地址为 http://www.cplusplus.com/reference/iostream/