如何使用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:这是一个较大问题的减少问题。我解析文件的方式导致了这个问题。
答案 0 :(得分:2)
getline
提及您jaggedSpire和push_back
"\n"
自己{/ 3}}:
ifstream input("doc.txt");
vector<string> contents;
for (string line; getline(input, line);) {
istringstream str(line);
for (string word; str >> word;) {
contents.push_back(word);
}
contents.push_back("\n");
}
答案 1 :(得分:1)
如果您希望专门使用operator>>
并且您在技术上不需要专门使用字符串,那么您可以简单地创建一个自定义类,其中包含从{{1}读入时所需的行为}。它甚至可以(大部分)是字符串的包装器,在读取初始空格时具有自定义行为。
istream
字符串read in运算符会自动忽略所有preceding whitespace到一系列非空白字符,如当前语言环境所定义。这是你想要改变的行为,事实证明这样做非常简单。
初始空格的处理通常由称为sentry对象的东西执行,该对象还检查流是否有效,并设置流的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
的字符串重载会生成并检查一个哨兵,然后读取,直到遇到空格,流的结尾或读取失败。我们可以简单地确保它的哨兵不会通过自己处理它来遇到空白。
因此,我们的自定义类'custom operator>>
的最终读入结构将如下所示:
由于我们只关注我们的空白中的'\ n'字符,这也很简单:只要在流有效时循环(如果在达到我们的任一条件之前它用完了空格,则设置{{1}就像我们想要的那样)并且如果两个条件之一是net,则退出循环:我们得到一个换行符,或者我们得到一个非空白字符。再次,简单易懂:
operator>>
完成后,我们设置了一个ostream运算符,以便于打印:
failbit
并测试我们的代码:
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
}
打印出来:
std::ostream& operator<<(std::ostream& out, const StringAndNewline& str){
return out << str.str();
}
就像我们想要的一样! Live on Coliru
如果你真的想轻松地将包装类转换为字符串,你甚至可以编写一个字符串运算符,但我会把它留给你。
答案 2 :(得分:0)
尝试使用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 }
答案 3 :(得分:-1)
首先,您已经在流的构造函数中作为const char *传递。 其次,流读取器读取字符而不是空格,这就是它知道何时切割成字符串的方式。
通常我们读取一个二进制文件,读者知道有一个字符告诉我们什么时候跳过一行着名的\ n但它与平台的不同之处(Win,Unix)。