0

I want to skip blank line when readhing a file.

I've tried if(buffer == "\n") and if(buffer.empty()), but it not work. 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;
}
Karmylr
  • 29
  • 3
  • 1
    If that doesn't work, the line is not blank. Sidenote: You don't need to supply `ios::in` to an `ifstream`. It's opening it for reading automatically. – Ted Lyngmo Jan 20 '23 at 07:03
  • 1
    Your code works fine for me. Are you reading a Windows file on a Linux system? – Tim Roberts Jan 20 '23 at 07:04
  • 1
    Is a string like " " (i.e. just three space characters) expected to be considered as a blank line? – Jeremy Friesner Jan 20 '23 at 07:05
  • If you are reading a Windows file on Linux: https://stackoverflow.com/questions/45956271/stdgetline-reads-carriage-return-r-into-the-string-how-to-avoid-that – VLL Jan 20 '23 at 07:09
  • (1) Define “blank”. A line made of spaces and/or tabs is not empty. (2) A solution would be to write a function that checks `buffer` for white spaces. Most efficient would be a simple loop. (3) If this is not the actual problem, do you really need `getline`? `>>` knows how to skip white spaces. – zdf Jan 20 '23 at 07:16
  • what is inside the file? What do you get printed to the console? – 463035818_is_not_an_ai Jan 20 '23 at 07:17
  • What is the input? What is the behaviour? "it not work" is not a useful problem description! Please take the [tour] and read [ask]. Also, consider learning how to use a debugger, it might make this much easier for you to solve yourself. – Ulrich Eckhardt Jan 20 '23 at 07:18
  • if others are right and the line is not actually empty: https://en.cppreference.com/w/cpp/string/byte/isspace – 463035818_is_not_an_ai Jan 20 '23 at 07:19
  • Extend `cout< – Yunnosch Jan 20 '23 at 07:20
  • 1
    `buffer == "\n"` will never work because `getline` does not include the newline in the returned string. If `buffer.empty()` does not work then it can only be because the line you are reading does include spaces or tabs or some similar characters. So you need to test for that. Try removing leading and trailing whitespace and then check if the string is empty. That would be the usual way to solve this problem. – john Jan 20 '23 at 07:42
  • If you want the line to contain only visible characters, you can try checking that at least one character is "non space" in the iterative line. https://en.cppreference.com/w/cpp/string/byte/isspace – Vahan Jan 20 '23 at 08:44
  • This doesn't address the question, but get in the habit of initializing objects with meaningful values rather than default-initializing them and immediately overwriting the default values. In this case that means changing `ifstream file_pointer; file_pointer.open("rules.txt", ios::in);` to `ifstream file_pointer("rules.txt", ios::in);`. Also, you don't need to call `file_pointer.close();`; the destructor will do that. – Pete Becker Jan 20 '23 at 15:07

2 Answers2

1

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. Importing everything en masse with using namespace std is almost always a bad idea.
  • C++ file streams are not pointers. 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. Let it close at object destruction (which you did).
  • Report errors to standard error and signal program failure by returning 1 from main().
  • Print normal output to standard output and signal program success by returing 0 from main().

It is likely that std::any_of() and lambdas are probably not something you have studied yet. There are all kinds of ways that is_blank() could have been written:

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. (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.

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.

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.

Dúthomhas
  • 8,200
  • 2
  • 17
  • 39
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).

#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 ".

(2) If this is a problem, you could use:

while (getline(cin, line))
  if (line.find_first_not_of(" \t") != string::npos)
    cout << "got: " << line << endl;
zdf
  • 4,382
  • 3
  • 18
  • 29