последовательное чтение текстового файла в C ++ - PullRequest
1 голос
/ 19 марта 2011

В C ++ я хочу последовательно читать слова из текстового файла и сохранять каждое слово в массиве? После этого я выполню некоторую операцию с этим массивом. Но я не знаю, как справиться с первым этапом: последовательно читать слова из текстового файла и сохранять каждое слово в массиве. Я должен пропустить те знаки препинания, которые включают ".", ",", "?"

Ответы [ 5 ]

1 голос
/ 19 марта 2011

Для этого вам нужно использовать потоки.Взгляните на примеры здесь: Ввод / вывод с файлами

0 голосов
/ 19 марта 2011

Еще одна возможность, используя (мой обычный) специальный фасет:

class my_ctype : public std::ctype<char> {
public:
    mask const *get_table() { 
        // this copies the "classic" table used by <ctype.h>:
        static std::vector<std::ctype<char>::mask> 
            table(classic_table(), classic_table()+table_size);

        // Anything we want to separate tokens, we mark its spot in the table as 'space'.
        table[','] = (mask)space;
        table['.'] = (mask)space;
        table['?'] = (mask)space;

        // and return a pointer to the table:
        return &table[0];
    }
    my_ctype(size_t refs=0) : std::ctype<char>(get_table(), false, refs) { }
};

Используя это, читать слова довольно легко:

int main(int argc, char **argv) { 
    std::ifstream infile(argv[1]);   // open the file.

    infile.imbue(std::locale(std::locale(), new my_ctype());  // use our classifier

    // Create a vector containing the words from the file:
    std::vector<std::string> words(
        (std::istream_iterator<std::string>(infile)),
        std::istream_iterator<std::string>());

    // and now we're ready to process the words in the vector
    // though it might be worth considering using `std::transform`, to take
    // the input from the file and process it directly.
0 голосов
/ 19 марта 2011

Вы знаете, сколько слов вы будете читать? Если нет, вам нужно будет увеличивать массив по мере того, как вы будете читать все больше и больше слов. Самый простой способ сделать это - использовать стандартный контейнер, который сделает это за вас: std::vector. Читать слова, разделенные пробелом, легко, так как это стандартное поведение std::ifstream::operator>>. Удаление знаков препинания требует дополнительной работы, поэтому мы вернемся к этому позже.

Основной рабочий процесс для чтения слов из файла выглядит следующим образом:

#include <fstream>
#include <string>
#include <vector>

int main()
{
    std::vector<std::string> words;
    std::string w;
    std::ifstream file("words.txt");  // opens the file for reading

    while (file >> w)  // read one word from the file, stops at end-of-file
    {
        // do some work here to remove punctuation marks            
        words.push_back(w);
    }

    return 0;
}

Предполагая, что вы делаете здесь домашнее задание, реальный ключ заключается в том, чтобы узнать, как убрать знаки препинания с w перед добавлением его в вектор. Я хотел бы изучить следующие концепции, чтобы помочь вам:

  • Идиома erase-remove . Обратите внимание, что std::string ведет себя как контейнер char.
  • std::remove_if
  • Функция ispunct в библиотеке cctype

Не стесняйтесь задавать дополнительные вопросы, если у вас возникли проблемы.

0 голосов
/ 19 марта 2011

Звучит как домашняя работа. Если это так, пожалуйста, будьте откровенны.

Прежде всего, в C ++ почти всегда плохая идея использовать необработанный массив - использование вектора - гораздо лучшая идея. Что касается вашего вопроса о пунктуации - это ваш клиент, но я склонен разделять пробелы.

В любом случае, вот простой способ сделать это, использующий преимущество operator>>(istream&, string&), разделяющее пробелы по умолчанию.

ifstream infile("/path/to/file.txt");
vector<string> words;
copy(istream_iterator<string>(file), istream_iterator<string>(), back_inserter(words));
0 голосов
/ 19 марта 2011

Вот полная программа, которая считывает слова из файла с именем «filename», сохраняет их в std::vector и удаляет пунктуацию из слов.

#include <algorithm>  // iostream, vector, iterator, fstream, string

struct is_punct {
    bool operator()(char c) const {
        static const std::string punct(",.:;!?");
        return punct.find(c) != std::string::npos;
    }
};

int main(int argc, char* argv[])
{
    std::ifstream in("filename");
    std::vector<std::string> vec((std::istream_iterator<std::string>(in)),
                                 std::istream_iterator<std::string>());
    std::transform(vec.begin(), vec.end(),
                   vec.begin(),
                   [](std::string s) {
                       s.erase(std::remove_if(s.begin(), s.end(), is_punct()),
                               s.end());
                       return s;
                   });
    // manipulate vec
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...