简体   繁体   English

读取C++文件时如何跳过空行?

[英]How to skip blank line when reading file in C++?

I want to skip blank line when readhing a file.我想在读取文件时跳过空行。

I've tried if(buffer == "\n") and if(buffer.empty()), but it not work.我试过 if(buffer == "\n") 和 if(buffer.empty()),但它不起作用。 I did like this:我确实喜欢这样:

#include <iostream>
#include <fstream>

using namespace std;

int main()
{
    ifstream file_pointer;
    file_pointer.open("rules.txt", ios::in);
    if(!file_pointer.is_open())
    {
        cout << "failed to read rule file." << endl;
        return 0;
    }
    string buffer;
    while(getline(file_pointer, buffer))
    {
        if(buffer.empty())
        {
            continue;
        }
        if(buffer == "\n")
        {
            continue;
        }
        cout << buffer << endl;
    }
    file_pointer.close();
    return 0;
}

The problem is that a “blank” line need not be “empty”.问题是“空白”行不一定是“空的”。

#include <algorithm>  // std::any_of
#include <cctype>     // std::isspace
#include <fstream>
#include <iostream>

//using namespace std;

bool is_blank( const std::string & s )
{
    return std::all_of( s.begin(), s.end(), []( unsigned char c )
    {
        return std::isspace( c );
    } );
}

int main()
{
    std::ifstream rules_file("rules.txt");
    if(!rules_file)
    {
        std::cerr << "failed to read rule file." << endl;
        return 1;
    }
    std::string line;
    while(getline(rules_file, line))
    {
        if(is_blank(line))
        {
            continue;
        }
        std::cout << line << "\n";
    }
    return 0;
}

A few notes.一些注意事项。

  • Get used to writing std:: infront of things from the Standard Library.习惯于在标准库中编写std:: infront 。 Importing everything en masse with using namespace std is almost always a bad idea. using namespace std大量导入所有内容几乎总是一个坏主意。
  • C++ file streams are not pointers. C++ 文件流不是指针。 Moreover, be descriptive with your names.此外,用你的名字描述。 It makes reading your code easier for your future self.它使您未来的自己更容易阅读您的代码。 Honest!诚实!
  • Open a file at the file stream object creation.在文件 stream object 创建时打开一个文件。 Let it close at object destruction (which you did).让它在 object 破坏时关闭(你这样做了)。
  • Report errors to standard error and signal program failure by returning 1 from main() .通过从main()返回1向标准错误报告错误并指示程序失败。
  • Print normal output to standard output and signal program success by returing 0 from main() .将正常的 output 打印为标准的 output 并通过从main()返回0来表示程序成功。

It is likely that std::any_of() and lambdas are probably not something you have studied yet. std::any_of()和 lambda 可能不是您研究过的东西。 There are all kinds of ways that is_blank() could have been written: is_blank()可以有多种写法:

bool is_blank( const std::string & s )
{
  for (char c : s)
    if (!std::isspace( (unsigned char)c ))
      return false;
  return true;
}

Or:或者:

bool is_blank( const std::string & s )
{
  return s.find_first_not_of( " \f\n\r\t\v" ) == s.npos;
}

Etc.等等。

The reason that the checking for newline didn't work is that getline() removes the newline character(s) from the input stream but does not store it/them in the target string.检查换行符不起作用的原因是getline() ) 从输入 stream 中删除了换行符,但没有将它/它们存储在目标字符串中。 (Unlike fgets() , which does store the newline so that you know that you got an entire line of text from the user.) C++ is much more convenient in this respect. (与fgets()不同,存储换行符,以便您知道您从用户那里得到了整行文本。)C++ 在这方面要方便得多。

Overall, you look to be off to a good start.总的来说,你看起来有了一个好的开始。 I really recommend you make yourself familiar with a good reference and look up the functions you wish to use.我真的建议您熟悉一个很好的参考资料并查找您想要使用的功能。 Even now, after 30+ years of this, I still look them up when I use them.即使是现在,经过 30 多年的使用,我仍然会在使用它们时查看它们。

One way to find good stuff is to just type the name of the function in at Google: “cppreference.com getline” will take you to the ur-reference site.找到好东西的一种方法是在 Google 中输入 function 的名称:“cppreference.com getline”将带您到 ur-reference 站点。

You can skip blank lines when reading a file in C++ by using the getline() function and checking the length of the resulting string.通过使用 getline() function 并检查结果字符串的长度,您可以在读取 C++ 中的文件时跳过空行。 Here is an example of how you can do this:以下是如何执行此操作的示例:

#include <fstream>
#include <string>

int main() {
    std::ifstream file("myfile.txt");
    std::string line;

    while (std::getline(file, line)) {
        if (line.length() == 0) {  // check if the line is empty
            continue; // skip the iteration
        }
        // process the non-empty line
    }
    file.close();
    return 0;
}

You can also use the std::stringstream class to skip blank lines, here is an example:您还可以使用 std::stringstream class 来跳过空行,这是一个示例:

#include <fstream>
#include <sstream>
#include <string>

int main() {
    std::ifstream file("myfile.txt");
    std::string line;

    while (std::getline(file, line)) {
        std::stringstream ss(line);
        if (ss >> line) { // check if the line is empty
            // process the non-empty line
        }
    }
    file.close();
    return 0;
}

(1) Here's a solution using the ws manipulator in conjunction with the getline function to ignore leading white-space while reading lines of input from the stream. ws is a manipulator that skips whitespace characters ( demo ). (1)这是一个将ws操纵器与getline function 结合使用的解决方案,以在读取来自ws的输入行时忽略前导空白。ws 是一个跳过空白字符的操纵器(演示)。

#include <iostream>
#include <string>

int main() 
{
  using namespace std;

  string line;
  while (getline(cin >> ws, line)) 
    cout << "got: " << line << endl;
  return 0;
}

Note that the spaces are removed even if the line is not empty ( " abc " becomes "abc " .请注意,即使该行不为空( " abc "变为"abc " ,空格也会被删除。

(2) If this is a problem, you could use: (2)如果这是一个问题,您可以使用:

while (getline(cin, line))
  if (line.find_first_not_of(" \t") != string::npos)
    cout << "got: " << line << endl;

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM