Search code examples
c++ubuntufstreamifstreamofstream

ifstream ignoring spaces and new lines - why?


So I am writing a simple program just trying to understand why it is ignoring spaces (it treats them as new lines) and why it does not account for new lines.

Language: C++

Platform: Kubuntu 13.04

Compiler: g++

Code:

 unsigned int lines;
 string line_content;
 ifstream r_tftpd_hpa("/etc/default/tftpd-hpa"); // open file

    // test for errors
if ( r_tftpd_hpa.fail() ) {
    cerr << "Error opening file: \"/etc/default/tftpd-hpa\"" << endl;
    exit(1);
}

    // loop through file until end
while ( !r_tftpd_hpa.eof() ) {
    r_tftpd_hpa >> line_content;
    lines++;

                          // I also tried with \n
    if ( line_content[0] == ' ' ) { // my failed attempt at catching spaces
        cout << endl << "Found empty line: " << lines << endl;
    }

    cout << "Line: " << lines << " content: " << line_content << endl;
}

Output:

 Line: 1 content: #
 Line: 2 content: /etc/default/tftpd-hpa
 Line: 3 content: TFTP_USERNAME="tftp"
 Line: 4 content: TFTP_DIRECTORY="/var/lib/tftpboot"
 Line: 5 content: TFTP_ADDRESS="0.0.0.0:69"
 Line: 6 content: TFTP_OPTIONS="--secure"
 Line: 7 content: TFTP_OPTIONS="--secure"   

The file itself:

 # /etc/default/tftpd-hpa

 TFTP_USERNAME="tftp"
 TFTP_DIRECTORY="/var/lib/tftpboot"
 TFTP_ADDRESS="0.0.0.0:69"
 TFTP_OPTIONS="--secure"

This file consists of 6 lines, however it seems to think it is 7. It counts the space after # in line 1 as a new line and ignores the space at line two in the original file. Also it prints line 6 and 7 as if there were two of the same line, there is not.

Any idea what is going on here? How do we deal with spaces and newlines?


Solution

  • The operator >> eats any whitespaces (newline, tab, space). If you need to count the number of lines, you can use the getline function.

    #include <cassert>
    #include <iostream>
    #include <fstream>
    #include <string>
    
    using namespace std;
    
    int main()
    {
      unsigned lines = 0;
      string line_content;
    
      ifstream r_tftpd_hpa ("tftpd-hpa");
      assert(r_tftpd_hpa);
    
      while ( getline(r_tftpd_hpa, line_content) ) {
        lines++;
    
        if ( line_content[0] == ' ' ) { // my failed attempt at catching spaces
          cout << endl << "Found empty line: " << lines << endl;
        }
    
        cout << "Line: " << lines << " content: " << line_content << endl;
      }
    
      return 0;
    }
    

    gives me:

    Line: 1 content: # /etc/default/tftpd-hpa
    Line: 2 content: 
    Line: 3 content: TFTP_USERNAME="tftp"
    Line: 4 content: TFTP_DIRECTORY="/var/lib/tftpboot"
    Line: 5 content: TFTP_ADDRESS="0.0.0.0:69"
    Line: 6 content: TFTP_OPTIONS="--secure"