2013-05-11 3 views
0

Итак, я пишу простую программу, просто пытаясь понять, почему она игнорирует пробелы (она рассматривает их как новые строки) и почему она не учитывает новые строки.ifstream игнорирует пробелы и новые строки - почему?

Язык: C++

Платформа: Kubuntu 13,04

Компилятор: г ++

Код:

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 в качестве новой строки и игнорирует пространство на второй строке в исходном файле. Также он печатает строку 6 and 7, как если бы были две одинаковые строки, их нет.

Любая идея, что здесь происходит? Как мы имеем дело с пробелами и новыми символами?

ответ

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" 
+0

Параметр 'noskipws' часть сделал это идти очень далеко, линия: 1159352 Содержание: Line: 1159353 Содержание: и так далее. Часть 'getline' частично работала, однако она все же пропустила первую строку, начинающуюся с ** # **. – dusz

+0

@dusz Я пробовал код, и он работал нормально. См. Мой обновленный пост с полной программой. – Yang

+1

Спасибо, линия, которая сделала трюк: 'assert()', нужно будет сделать еще некоторое чтение, установив в качестве ответа. – dusz

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)) 
+0

Это действительно лучше, однако теперь кажется, что он игнорирует первую строку _ # _, почему? – dusz

Смежные вопросы