从C++中的文件中读取字符串

por*_*ork 2 c++ string file-io fstream

我正在尝试将字符串直接存储到一个文件中以便稍后在C++中读取(基本上对于完整的范围我试图在文件中存储带有字符串变量的对象数组,并且这些字符串变量将通过类似对象读取[0] .string).但是,每次我尝试读取字符串变量时系统都会给我一个混乱的错误.以下代码是我正在尝试的基本部分.

#include <iostream>
#include <fstream>
using namespace std;

/*
//this is run first to create the file and store the string
int main(){
    string reed;
    reed = "sees";
    ofstream ofs("filrsee.txt", ios::out|ios::binary);
    ofs.write(reinterpret_cast<char*>(&reed), sizeof(reed));
    ofs.close();

}*/

//this is run after that to open the file and read the string
int main(){
    string ghhh;
    ifstream ifs("filrsee.txt", ios::in|ios::binary);
    ifs.read(reinterpret_cast<char*>(&ghhh), sizeof(ghhh));
    cout<<ghhh;
    ifs.close();
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

第二部分是当我尝试阅读它时,事情变得混乱.对不起,如果之前有人询问过,我已经看过类似的问题了,但大多数都和我想做的有点不同,或者我真的不明白他们想做什么(还是挺的)这是新的).

pae*_*bal 5

我究竟做错了什么?

您正在读取文件并尝试将数据放入字符串结构本身,覆盖它,这是完全错误的.

由于其可以在验证http://www.cplusplus.com/reference/iostream/istream/read/,您使用的类型是错误的,你知道,因为你必须强制std::string进入char *使用reinterpret_cast.

C++提示:在C++中使用a reinterpret_cast(几乎)总是表明你做错了什么.

为什么读取文件这么复杂?

很久以前,阅读文件很容易.在一些类似Basic的语言中,你使用了这个功能LOAD,并且vo!,你有你的文件.那么为什么我们现在不能这样做呢?

因为你不知道文件中有什么.

  • 它可能是一个字符串.
  • 它可以是一个序列化的结构数组,其中包含从内存中转储的原始数据.
  • 它甚至可以是直播流,即连续附加的文件(日志文件,标准输入,等等).
  • 您可能希望逐字读取数据
  • ......或逐行......
  • 或者文件太大而不适合字符串,所以你想要按部分阅读.
  • 等等..

更通用的解决方案是使用函数get(参见http://www.cplusplus.com/reference/iostream/istream/get/)读取文件(因此,在C++中,使用fstream),每字节字节数,并执行你自己把它转换成你期望的类型的操作,并在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 ;
}
Run Code Online (Sandbox Code Playgroud)

如果您正在使用启用了C++ 11的编译器,则可以添加此重载函数,这将不会花费任何成本(在C++ 03中,baring优化,它可能会花费您一个临时对象):

std::string loadFile(const std::string & p_name)
{
    std::string content ;
    loadFile(p_name, content) ;
    return content ;
}
Run Code Online (Sandbox Code Playgroud)

现在,为了完整起见,我写了相应的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 ;
}
Run Code Online (Sandbox Code Playgroud)

在这里,我用来测试这些功能的"主要":

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" ;
    }
}
Run Code Online (Sandbox Code Playgroud)

更多?

如果您想要做更多的事情,那么您需要浏览C++ IOStreams库API,网址http://www.cplusplus.com/reference/iostream/