使用c++流读取换行符
Read newline using stream C++
如何使用c++>>操作符读取新行?
ifstream input("doc.txt".c_str());
vector<string> contents;
while (input >> word) {
contents.push_back(word);
}
对于文件:
hello
world
C++ is the best tool
应该返回
hello
n
world
n
C++
is
the
best
tool
p/S:这是一个大问题的简化版。我解析文件的方式导致了这个问题。您可以自己使用std::getline
, push_back
和"n"
,正如jaggedSpire所提到的:
std::ifstream input("doc.txt");
std::vector<std::string> contents;
for (std::string line; std::getline(input, line);) {
std::istringstream str(line);
for (std::string word; str >> word;) {
contents.push_back(word);
}
contents.push_back("n");
}
如果你正在寻找具体使用operator>>
和你不技术上需要使用字符串具体,你可以简单地做一个自定义类的行为,你想当它从istream
读取。它甚至可以(主要)作为字符串的包装器,在读取初始空白时具有自定义行为。
class StringAndNewline{
std::string str_;
friend std::istream& operator>>(std::istream& in, StringAndNewline& str);
public:
StringAndNewline() : str_(){}
StringAndNewline(std::string str) : str_(str){}
const std::string& str() const noexcept {return str_;}
std::string release() {return std::move(str_);}
};
在操作符中读取的字符串自动忽略前面的所有空格,而变成由当前语言环境定义的非空白字符序列。这是你想要改变的行为,而且事实证明,这样做非常简单。
初始空格的处理通常由称为哨兵对象的东西执行,该对象还检查流是否有效,如果流位于文件末尾,则设置流的failbit
。虽然它的默认行为是在遇到非空白字符之前使用空白字符,但这是由其构造函数中的标志控制的,因此我们可以使用它提供的非常好的封装流有效性检查。
operator>>
的字符串重载创建并检查一个哨兵,然后读取,直到遇到空格、流结束或读取失败。我们可以简单地通过自己处理它来确保它的哨兵永远不会遇到空白。
operator>>
的最终读入结构看起来像这样:
- 设置非空格吃哨
- 检查哨兵,如果它无效,返回失败的流
- 处理空白
- 读取数据到包装字符串
- 返回流
因为我们只关心空格中的'n'字符,这也很简单:只要在流有效时循环(如果在达到我们的任何一个条件之前空间耗尽,它就像我们想要的那样设置failbit
),如果两个条件之一是net,则退出循环:我们得到一个换行字符,或者我们得到一个非空白字符。同样,非常简单:
std::istream& operator>>(std::istream& in, StringAndNewline& str){
std::istream::sentry sentry{in, true}; // make a sentry that doesn't eat whitespace
if(!sentry){return in;} // check the sentry
std::locale
presentLocale{}; // get the present locale
char presentChar;
while(in.get(presentChar)){ // while the stream is valid
if(presentChar == 'n'){ // if we get a newline
str.str_ = "\n"; // set the string to an escaped newline
break; // exit the loop
}
// if we get a non-whitespace character
else if(!std::isspace(presentChar, presentLocale)){
in.unget(); // replace the character in the stream
in >> str.str_; // take advantage of the existing string operator
break; // done with loop
}
}
return in; // return the istream, whatever state it might be in
}
完成后,为了便于打印,我们设置一个ostream操作符:
std::ostream& operator<<(std::ostream& out, const StringAndNewline& str){
return out << str.str();
}
和测试我们的代码:
int main (){
std::istringstream file(
"hellon"
"worldn"
"C++ is the best tool"
);
StringAndNewline
wordOrNewline;
while(file >> wordOrNewline){
std::cout << wordOrNewline << 'n';
}
}
打印这个:
hello
n
world
n
C++
is
the
best
tool
就像我们想要的!Live on Coliru
如果您真的想要轻松地将包装器类转换为字符串,您甚至可以编写一个字符串操作符,但我将把它留给您。
尝试使用getline (http://www.cplusplus.com/reference/istream/istream/getline/)。Getline将遍历每一行(直到它看到新的行字符),并在到达文件末尾时返回0。因此,在每次调用getline并打印它之后,也会打印n。这里有一个例子来解决你的问题,randFile是一个随机文件,里面有文本。
1 #include <iostream>
2 #include <fstream>
3 int main(){
4
5 std::ifstream myFile("randFile", std::ifstream::in);
6 char s[BUFSIZ];
7
8 while(myFile.getline(s, BUFSIZ)){
9 std::cout << s << std::endl;
10 std::cout << "\n"<< std::endl;
11 }
12
13 return 0;
14 }
首先,您已经在流的构造函数中传递了const char *。其次,流读取器读取字符而不是空格,这就是它如何知道何时切到字符串的原因。
通常我们读取一个二进制文件,有一个读者知道的字符,当我们跳过一行时,它告诉我们著名的n,但它与平台(Win, Unix)不同。
- 从文本文件中读取数据并删除所有换行符空格,并在 C++ 控制台中显示
- 使用 fgets() 从键盘读取时从以前的输入读取换行符
- 为什么 ifstream 文件中的换行符 - 当被此代码读取时 - 占用 2 个字节
- 使用 getline 读取字符串,但每行中都有换行符
- 一次读取一个字符的文件,直到使用 read(2) 和 write(2) 换行符
- 如何使用ifstream c ++从带有换行符的文件读取字符串
- 您如何做到这一点,以便在C++中读取文件时在文件末尾有换行符
- 使用 c++ 读取文件时省略换行符
- 读取文件内容时未定义的字符,文件末尾没有换行符
- 如何仅当字符串流包含任何换行符时才从字符串流中读取行
- 为什么此代码在遇到换行符之前无法正确读取字符串?
- 读取整数对,直到文本输入文件中的换行符
- 正在读取由换行符分隔的文本文件.unix上的C++
- 编写一个C++ pgm 以从文件"input.txt"读取,每当遇到句点时插入换行符并将修改的内容写入"output.txt"
- 如何将换行符按钮更改为空格以完成从输入流的读取
- 使用 getline 仅读取换行符或文本
- 非常简单的C ++:在 fstream 中>>运算符在读取某些内容后是否删除换行符?
- 从文件读取数据时意外标记"换行符"附近出现语法错误
- 读取带引号的 CSV 数据,不带换行符作为结束行
- 从用换行符和逗号分隔的txt文件中读取