C++ IO vs Java IO

C++ IO vs Java IO

本文关键字:IO Java vs C++      更新时间:2023-10-16

请注意,这不是一个"优于"的讨论。

我是一个Java程序员,不知道如何做很多c++文件IO,这让我觉得非常愚蠢。

我需要为XML解析器做一个非常简单的适配器,就像下面的代码说

在Java中,我可以使用:

BufferedReader reader = new BufferedReader(
  new InputStreamReader(xmlInputStream));
String xml = "";
String line = null;
while ((line = reader.readLine()) != null) {
  xml += line + "n";
}
return xmlParser11.parse(xml);

对我来说最大的问题是如何处理c++中的reader

非常感谢!

为了给一个更温和的介绍,下面的c++代码正在尽可能地模仿您的Java代码:

#include <iostream>
#include <fstream>
#include <string>
int main()
{
    std::ifstream xmlInputStream("input.xml"); // or istringstream or istream
    std::string xml;
    std::string line;
    while(getline(xmlInputStream, line))
    {
        xml += line + "n";
    }
    //return xmlParser11.parse(xml);
    std::cout << xml << 'n';
}

当然,在c++中不需要通过循环将输入流读入字符串:输入流可以用一对迭代器表示,可以有多种不同的使用方式:

#include <iostream>
#include <fstream>
#include <string>
#include <iterator>
int main()
{
    std::ifstream xmlInputStream("input.xml");
    std::istreambuf_iterator<char> beg(xmlInputStream), end;
    std::string xml(beg, end);
    std::cout << xml << 'n';
}

但通常甚至不需要临时字符串对象:c++解析器可以直接操作输入流或一对迭代器

如果您正在从文件中读取,您可以这样做:

std::ifstream file("myfile.xml");
std::stringstream xml;
std::copy(std::istreambuf_iterator<char>(file), std::istreambuf_iterator<char>(), 
          std::ostream_iterator<char>(xml));

这将把整个文件读入std::stringstream xml,包括换行符等(就像在示例代码中一样)。然后您可以使用xml.str()作为std::string访问它。

这是使用STL -你是想问c++还是你想要C等效(即使用fopen, read等)?

// main.cpp
#include <iostream>
#include <fstream>
#include <string>
using namespace std;
int main() {
  string line;
  string xml;
  ifstream myfile("example.txt");
  if( myfile.is_open() ) {
    while( myfile.good() ) {
      getline (myfile,line);
      xml += line + "n";
    }
    myfile.close();
  }
  else
     cout << "Unable to open file"; 
  return 0;
}

您可以在c++中做完全相同的事情:

std::ifstream reader( xmlInputStream.c_str() );
if ( !reader.is_open() ) {
    //  error handling here...
}
std::string xml;
std::string line;
while ( std::getline( reader, line ) ) {
    xml += line + 'n';
}

这可能不是最好的解决方案,但它已经相当好。我可能会这样写:

std::string xml(
    (std::istringstream_iterator<char>( reader )),
    (std::istringstream_iterator<char>()) );

(注意至少需要一组额外的括号,由于c++解析语句的方式异常否则。)

甚至:

std::string
readCompleteFile( std::istream& source )
{
    return std::string(
        std::istringstream_iterator<char>( source ),
        std::istringstream_iterator<char>() );
}

(看,没有变量:-)!)这两个解都成立换行符在原始文件中,所以您不需要添加它们

对编辑的几点评论:

    这将是极其罕见的将' std::ifstream& '作为参数,而不是"std:: istream"。你唯一一次看到' std::ifstream '是在
  • 关于您是否成功打开的错误检查流是否属于您打开的位置,而不是在某个函数中用(应该是什么)一个' std::istream& '调用。(你不能检查' std::istream '是否打开,因为对于许多流类型,"打开"的概念不存在。)
  • 不清楚"XML"的语义是什么:是吗值,在这种情况下,它支持复制和赋值永远不要动态地分配一个,并按值返回"XMLParser11:解析";或者这是某种实体对象,在在这种情况下,你返回一个指针(或者可能是一个' std::auto_ptr ',以特别确保客户端知道他有责任删除它。
  • 在任何情况下,如果' XML '是动态分配的,您应该将其保存在' XMLParser11::Parse '中的' std::auto_ptr '中,以确保如果有异常,它将被正确地析构在它的分配和返回之间。

我将为BufferedReader实现一个析构函数,它将销毁所有已使用的资源并释放该对象生命周期内使用的任何内存。之后,我将调用BufferedReader对象的delete

您可以从这里开始查看