当前位置:  开发笔记 > 编程语言 > 正文

此代码用于输出Hello World.但它输出0x22fed8

如何解决《此代码用于输出HelloWorld.但它输出0x22fed8》经验,为你挑选了4个好方法。

我正在学习C++中的文件处理,但这里有一个问题.我正在尝试读取文件.此代码用于输出Hello World.但它输出0x22fed8.

#include 
#include 

using namespace std;

    int main()
    {
        fstream file;
        file.open("test.txt",ios::in|ios::out);
        file << "Hello World";
        cout << file;
        file.close();

        return 0;
    }

我究竟做错了什么?



1> Konrad Rudol..:

简单解决方案

正如其他人所指出的那样,直接将文件打印到流不起作用.打印文件内容需要打开另一个从文件读取的,或者将流的读指针重新设置为开头,然后再次读取整个文件(正如其他人所示).

C++不会自动执行此操作,但您可以手动执行此操作(此处,打开新流):

ifstream ifs("filename");

现在,将文件内容写入另一个流是一个微不足道的补充.只需编写文件缓冲区,而不是编写文件:

cout << ifs.rdbuf() << endl;

就这样!逐行读取文件不需要循环.

测试有效的流

当我们讨论循环时,请注意以下列方式在循环中读取文件的代码:

while ( !file.eof() )

当出现读数错误时,此代码会产生无限循环.这种情况在很多很多情况下都会发生.考虑例如,在您阅读文件时删除文件,或者有人删除包含该文件的USB设备或文件格式错误.所有这些情况都会在这里创建一个无限循环.永远不要eof在溪流中测试.

幸运的是,这个问题的解决方案也很简单.此外,它解释了为什么你的原始代码产生了如此奇怪的结果.事实上,C++中的流有一个隐式转换为类似bool类型.由于其他地方解释的原因(提示:安全bool成语),它实际上转换为void*.

这样可以轻松测试流是否处于有效,非最终状态并且可以安全地读取.因此,我们可以适当地重新构造循环:

while (file) …

上面的代码依赖于转换void*发生.任何非null指针都表示有效的流.现在,代码中也会出现同样的情况:

cout << file;

由于没有适当的重载operator <<需要流,C++寻找其他重载并找到指针的重载.所以它隐含地调用这样的东西:

cout << static_cast(file);

好的解决方案

我已经解释了上面一个简单,有效的解决方案.但是,此解决方案需要重新打开文件并再次将其读取到内存中.这使所需的工作增加了一倍.我们可以通过引入一个类似于流的新类来实现这一点,并且实际上将每个输出一次发送到两个流.这样,您可以同时将数据写入文件和标准流.无需重新读取文件.

这个课本身很简单.以下完整代码演示了一般原则:

#include 
#include 

struct sinkpair {
    sinkpair(std::ostream& a, std::ostream& b) : a(a), b(b) { }

    // Forward all ouputs to both streams.
    template 
    sinkpair& operator <<(T const& value) {
        a << value;
        b << value;
        return *this;
    }

    // Explicit overload needed for manipulators such as `endl`.
    sinkpair& operator <<(std::ostream& (*manip)(std::ostream&)) {
        a << manip;
        b << manip;
        return *this;
    }

private:
    std::ostream& a;
    std::ostream& b;
};

int main() {
    std::ofstream ofs("test.txt");
    sinkpair sp(std::cout, ofs);
    sp << "Hello" << std::endl;
}



2> Andrei Taran..:

编辑:有mrree的建议.

ifstream fin("file.txt");

if (fin.is_open() == false) {
  // error
}

string line;

while( getline(fin, line) ) {  
  cout << line;
}



3> JaredPar..:

让我们来看看这条线

cout << file;

这个输出数字的原因是因为引擎盖下的fstream是一个文件指针.通过将文件传递给cout,你基本上要求一个fout的cout.这将默认为文件的基础句柄的值.

如果要输出文件的内容,则需要将其读入并逐行输出.

fstream file;
file.open("test.txt",ios::in|ios::out);
file << "Hello World";
file.seekg (0, ios::beg);
while ( !file.eof() ) {
  string temp;
  file >> temp;
  cout << temp << std::eol;
}

file.close();



4> Thomas L Hol..:
#include 
#include 

int main(int, char **) 
{
  std::ifstream input("test.txt");
  char c;                                                          
  while (input >> c) {
    std::cout << c;
  }
  return 0;
}

不要包含整个标准命名空间.如果需要输入文件流,请使用ifstream.

您想要输出文件的内容,而不是文件.

如果要写入文件,请将其读回并发送给stdout,

#include 
#include 

int main(int, char **)
{
  std::fstream file("test.txt",std::ios::in|std::ios::out);
  file << "Hello" << std::endl;
  file.seekp(std::ios::beg);
  char c;
  while (file >>c) {
      std::cout << c ;
  }
  return 0;
}

康拉德有最好的答案,但考虑高级方法:

#include 
#include 
#include 
#include 

int main(int, char **)
{
  std::fstream file("test.txt",std::ios::in|std::ios::out);
  file << "Hello" << std::endl;
  file.seekp(std::ios::beg);
  std::copy(
      std::istream_iterator(file),
      std::istream_iterator(), 
      std::ostream_iterator(std::cout)
      );
  return 0;
}

推荐阅读
贴进你的心聆听你的世界
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有