0

そのため、スペースを無視する理由 (スペースを改行として扱う) と改行を考慮しない理由を理解しようとする単純なプログラムを作成しています。

言語: 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 つあるかのように行を出力しますが、ありません。

ここで何が起こっているのか分かりますか?スペースと改行をどのように処理しますか?

4

2 に答える 2

1

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"
于 2013-05-11T15:34:38.683 に答える
1

これは、>>に抽出するために使用すると、std::string空白に到達するまで文字が読み取られるためです。つまり、期待どおりの行ではなく、「単語」を読み取ります。

で区切られた行を読みたい場合は、次\nを使用しますstd::getline

std::getline(r_tftpd_hpa, line_content);

ただし、ループeofの条件としてを使用すると、別の問題が発生します。whileファイルの終わりに達していないからといって、次の行の抽出が成功するとは限りません。これは通常、ファイル\nの終わりの前に があるファイルの終わりで発生します。が抽出され、\nEOF ビットが設定されないため、ループが続行され、別の行を抽出しようとします。これにより、ファイルの最後の行が 2 回読み取られたように見えます。これを回避するには、ループstd::getlineの状態に移動します。while

while (std::getline(r_tftpd_hpa, line_content))
于 2013-05-11T15:34:50.073 に答える