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