Прочитать всю строку, включая пробелы, из fstream

В настоящее время я работаю над небольшим проектом на С++ и сейчас немного запутался. Мне нужно прочитать определенное количество слов в строке, взятой из файла с помощью ifstream in(). Проблема с ним прямо сейчас заключается в том, что он продолжает игнорировать пробелы. Мне нужно подсчитать количество пробелов в файле, чтобы рассчитать количество слов. Есть ли способ, чтобы in() не игнорировал пробел?

ifstream in("input.txt");       
ofstream out("output.txt");

while(in.is_open() && in.good() && out.is_open())
{   
    in >> temp;
    cout << tokencount(temp) << endl;
}

person Magical Toast    schedule 24.01.2013    source источник
comment
std::getline   -  person jrok    schedule 25.01.2013
comment
Не могли бы вы включить фрагмент кода в свой вопрос? Ответы могут быть гораздо более конкретными, когда вопрос более ясен.   -  person Mogsdad    schedule 25.01.2013
comment
Вы можете настроить, должны ли потоки C++ игнорировать пробелы или нет, это называется skipws, если я правильно помню.   -  person Ulrich Eckhardt    schedule 25.01.2013
comment
Это пока условие такое глупое, что я даже не знаю, как его прокомментировать. Вы хотя бы fstream::operator bool()?   -  person Griwes    schedule 25.01.2013
comment
Что означает @Griwes, так это то, что вы можете просто делать while(in) {...}   -  person Nathan Monteleone    schedule 25.01.2013
comment
@NathanMonteleone, серьезно, тебе нужно сделать все настолько простым?   -  person Griwes    schedule 25.01.2013


Ответы (3)


Чтобы подсчитать количество пробелов в файле:

std::ifstream inFile("input.txt");
std::istreambuf_iterator<char> it (inFile), end;
int numSpaces = std::count(it, end, ' ');

Чтобы подсчитать количество пробелов в файле:

std::ifstream inFile("input.txt");
std::istreambuf_iterator<char> it (inFile), end;
int numWS = std::count_if(it, end, (int(*)(int))std::isspace);

В качестве альтернативы вместо подсчета пробелов вы можете подсчитывать слова.

std::ifstream inFile("foo.txt);
std::istream_iterator<std::string> it(inFile), end;
int numWords = std::distance(it, end);
person Robᵩ    schedule 24.01.2013
comment
+1 за трюк istreambuf_iterator‹char›. Мне было интересно, есть ли что-то в этом роде, что позволило бы вам сделать это с помощью одного итератора для всего файла :) - person Nathan Monteleone; 25.01.2013

Вот как бы я это сделал:

std::ifstream fs("input.txt");
std::string line;
while (std::getline(fs, line)) {
    int numSpaces = std::count(line.begin(), line.end(), ' ');
}

В общем, если мне нужно сделать что-то для каждой строки файла, я считаю std::getline наименее привередливым способом сделать это. Если мне нужны потоковые операторы оттуда, я в конечном итоге создам строковый поток только из этой строки. Это далеко не самый эффективный способ делать что-то, но я обычно больше озабочен тем, чтобы сделать это правильно и двигаться дальше по жизни для такого рода вещей.

person Nathan Monteleone    schedule 24.01.2013

Вы можете использовать count с istreambuf_iterator:

ifstream fs("input.txt");

int num_spaces = count(istreambuf_iterator<unsigned char>(fs),
                       istreambuf_iterator<unsigned char>(),
                       ' ');

изменить

Первоначально в моем ответе использовалось istream_iterator, однако, как указал @Robᵩ, это не работает.

istream_iterator будет перебирать поток, но предполагает форматирование пробелов и пропускает его. Мой пример выше, но использование istream_iterator вернуло нулевой результат, так как итератор пропустил пробелы, а затем я попросил его подсчитать оставшиеся пробелы.

istreambuf_iterator однако принимает по одному необработанному символу за раз, без пропусков.

Дополнительную информацию см. в разделе istreambuf_iterator vs istream_iterator.

person Peter Wood    schedule 24.01.2013
comment
Этот код не делает того, что вы думаете. На самом деле он всегда возвращает ноль. - person Robᵩ; 25.01.2013
comment
Спасибо за отзыв, @Robᵩ - person Peter Wood; 26.01.2013