ifstream忽略空格和新线 - 为什么?

时间:2013-05-11 15:32:28

标签: c++ ubuntu fstream ifstream ofstream

所以我正在编写一个简单的程序,试图理解它为什么忽略空格(它将它们视为新行)以及它为什么不考虑新行。

语言: C ++

平台: Kubuntu 13.04

编译器: g ++

代码:

 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;
}

输出:

 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"   

文件本身:

 # /etc/default/tftpd-hpa

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

此文件由6行组成,但它似乎认为它是7.它将第1行中#之后的空格计为新行,并忽略原始文件中第2行的空格。它还打印行6 and 7,好像有两条相同的行,没有。

知道这里发生了什么吗?我们如何处理空格和换行?

2 个答案:

答案 0 :(得分:0)

operator >>吃任何空格(换行符,制表符,空格)。如果需要计算行数,可以使用getline函数。

#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;
}

给了我:

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"

答案 1 :(得分:0)

这是因为使用>>提取到std::string只会读取字符,直到它到达空格。也就是说,它会读取一个“单词”,而不是您期望的那一行。

如果您想阅读由\n分隔的行,请使用std::getline

std::getline(r_tftpd_hpa, line_content);

但是,如果使用eof作为while循环的条件,则会遇到另一个问题。仅仅因为你尚未到达文件末尾,这并不意味着下一行提取将成功。这通常发生在文件末尾,文件末尾有\n。将提取\n并且不会设置EOF位,因此循环将继续并尝试提取另一行。这会导致文件的最后一行显示为两次。要解决此问题,请将std::getline移至while循环的条件:

while (std::getline(r_tftpd_hpa, line_content))