close()我使用时需要手动拨打电话std::ifstream吗?
例如,在代码中:
std::string readContentsOfFile(std::string fileName) {
std::ifstream file(fileName.c_str());
if (file.good()) {
std::stringstream buffer;
buffer << file.rdbuf();
file.close();
return buffer.str();
}
throw std::runtime_exception("file not found");
}
Run Code Online (Sandbox Code Playgroud)
我需要file.close()手动拨打电话吗?不应该ifstream使用RAII来关闭文件?
具体来说我很感兴趣istream& getline ( istream& is, string& str );.是否有ifstream构造函数的选项告诉它将所有换行编码转换为引擎盖下的'\n'?我希望能够打电话getline并优雅地处理所有行结尾.
更新:为了澄清,我希望能够编写几乎可以在任何地方编译的代码,并且几乎可以从任何地方获取输入.包括'\ r'没有'\n'的稀有文件.最大限度地减少软件用户的不便.
解决这个问题很容易,但我仍然对标准中正确处理所有文本文件格式的方式感到好奇.
getline读取一个完整的行,直到'\n',成为一个字符串.'\n'从流中消耗,但getline不包含在字符串中.到目前为止这很好,但是在'\n'之前可能会有一个'\ r'被包含在字符串中.
有三种类型的行结尾的文本文件中看到:"\n"是Unix机器上的常规结尾,"\ r"是在旧的Mac操作系统使用,Windows使用一对(我认为),"\ r"跟随'\n'.
问题是getline在字符串末尾留下'\ r'.
ifstream f("a_text_file_of_unknown_origin");
string line;
getline(f, line);
if(!f.fail()) { // a non-empty line was read
// BUT, there might be an '\r' at the end now.
}
Run Code Online (Sandbox Code Playgroud)
编辑感谢Neil指出这f.good()不是我想要的.!f.fail()是我想要的.
我可以自己手动删除它(请参阅此问题的编辑),这对于Windows文本文件很容易.但是我担心有人会输入一个只包含'\ r'的文件.在这种情况下,我认为getline将消耗整个文件,认为它是一行!
..那甚至不考虑Unicode :-)
..也许Boost有一种很好的方式从任何文本文件类型一次消耗一行?
编辑我正在使用它来处理Windows文件,但我仍然觉得我不应该这样做!这不会为'\ r'专用文件分叉.
if(!line.empty() && *line.rbegin() == '\r') {
line.erase( line.length()-1, 1);
}
Run Code Online (Sandbox Code Playgroud) 我有:
string filename:
ifstream file(filename);
Run Code Online (Sandbox Code Playgroud)
编译器抱怨ifstream文件和字符串之间没有匹配.我需要将文件名转换为某些内容吗?
这是错误:
error: no matching function for call to ‘std::basic_ifstream<char, std::char_traits<char> >::basic_ifstream(std::string&)’
/usr/include/c++/4.4/fstream:454: note: candidates are: std::basic_ifstream<_CharT, _Traits>::basic_ifstream(const char*, std::_Ios_Openmode) [with _CharT = char, _Traits = std::char_traits<char>]
Run Code Online (Sandbox Code Playgroud) 在以下代码中:
#include <iostream>
#include <fstream>
#include <string>
using namespace std;
int main() {
string x = "This is C++.";
ofstream of("d:/tester.txt");
of << x;
of.close();
ifstream read("d:/tester.txt");
read >> x;
cout << x << endl ;
}
Run Code Online (Sandbox Code Playgroud)
Output :This
由于>> operator读取到第一个空格,我得到了这个输出.如何将线提取回字符串?
我知道这种形式,istream& getline (char* s, streamsize n ); 但我想将它存储在一个字符串变量中.
我怎样才能做到这一点 ?
我目前正在用c ++编写一个程序,其中包括阅读大量的大文本文件.每行有~400.000行,极端情况下每行有4000或更多字符.仅供测试,我使用ifstream和cplusplus.com提供的实现读取其中一个文件.花了大约60秒,这太长了.现在我想知道,有没有一种直接的方法来提高阅读速度?
编辑:我使用的代码或多或少是这样的:
string tmpString;
ifstream txtFile(path);
if(txtFile.is_open())
{
while(txtFile.good())
{
m_numLines++;
getline(txtFile, tmpString);
}
txtFile.close();
}
Run Code Online (Sandbox Code Playgroud)
编辑2:我读的文件只有82 MB大.我主要说它可以达到4000,因为我认为可能有必要知道为了做缓冲.
编辑3:谢谢大家的答案,但考虑到我的问题似乎没有太大的改进空间.我必须使用readline,因为我想计算行数.将ifstream实例化为二进制文件也不会使读取速度更快.我将尝试尽可能地并行化它,至少应该起作用.
编辑4:显然我可以做一些事情.非常感谢你花了这么多时间,我非常感激!=)
在ifstreamC++的情况下,在什么条件failbit和badbit标志设置?
#include <iostream>
#include <fstream>
int main() {
std::fstream inf( "ex.txt", std::ios::in );
while( !inf.eof() ) {
std::cout << inf.get() << "\n";
}
inf.close();
inf.clear();
inf.open( "ex.txt", std::ios::in );
char c;
while( inf >> c ) {
std::cout << c << "\n";
}
return 0;
}
Run Code Online (Sandbox Code Playgroud)
我真的很困惑eof()功能.假设我的ex.txt的内容是:
abc
Run Code Online (Sandbox Code Playgroud)
它总是读取一个额外的字符,并-1在阅读时显示eof().但是inf >> c给出了'abc'的正确输出?任何人都可以帮我解释一下吗?
Implicit instantiation of undefined template 'std::basic_ifstream<char,std::char_traits<char>>'
#ifndef MAPPER_H
#define MAPPER_H
#include <iostream>
#include <string>
#include <vector>
#include "KeyValue.h"
#include "Parser.h"
using namespace std;
class Mapper
{
public:
Mapper(ifstream& infile);
~Mapper(void);
void loadTokens();
void showTokens();
void map();
void printMap();
void printMap(string map_fileName);
private:
ifstream inFile; //<-- is where the error is happening
vector<string> tokens;
vector<KeyValue> map_output;
Parser* parser;
};
#endif
Run Code Online (Sandbox Code Playgroud)
我甚至尝试过推杆std::ifstream但它仍然无效.
当我#include <fstream>代替的#include <iostream>,我在得到这些错误fstream.tcc和basic_ios.tcc:
'operator=' is a private member of 'std::basic_streambuf<char>' …
一个标准的习语是
while(std::getline(ifstream, str))
...
Run Code Online (Sandbox Code Playgroud)
所以如果这有效的话,我为什么不能说
bool getval(std::string &val)
{
...
std::ifstream infile(filename);
...
return std::getline(infile, val);
}
Run Code Online (Sandbox Code Playgroud)
g++ 说“ cannot convert 'std::basic_istream<char>' to 'bool' in return”。
值函数return中语句的布尔bool上下文是否与 的布尔上下文有所不同while(),以至于在一个上下文中执行的魔术转换std::basic_istream在另一个上下文中不起作用?
附录:这里显然有一些版本,也许还有语言标准依赖性。我在 g++ 8.3.0 中遇到了上述错误。但我在 gcc 4.6.3 或 LLVM (clang) 9.0.0 中没有得到它。
A.hpp:
class A {
private:
std::unique_ptr<std::ifstream> file;
public:
A(std::string filename);
};
Run Code Online (Sandbox Code Playgroud)
A.cpp:
A::A(std::string filename) {
this->file(new std::ifstream(filename.c_str()));
}
Run Code Online (Sandbox Code Playgroud)
我得到的错误被抛出:
A.cpp:7:43: error: no match for call to ‘(std::unique_ptr<std::basic_ifstream<char> >) (std::ifstream*)’
Run Code Online (Sandbox Code Playgroud)
有没有人知道为什么会这样?我已经尝试了很多不同的方法让它工作,但无济于事.