2014-11-23 6 views
3

Это еще один вопрос, на который я не могу найти ответ, потому что каждый пример, который я могу найти, использует векторы, и мой учитель не позволит нам использовать векторы для этого класса.stringstream с несколькими разделителями

мне нужно прочитать в обычной текстовой версии книги одного слова в то время, используя (любое число) пустых пространств
' ' и (любое число), не буквы символов в качестве разделителей; поэтому любые пробелы или знаки препинания в любой сумме должны отделять слова. Вот как я это сделал, когда это было необходимо только использовать пробелы в качестве разделителя:

while(getline(inFile, line)) { 
    istringstream iss(line); 

    while (iss >> word) { 
     table1.addItem(word); 
    } 
} 

EDIT: пример текста, читать, и как мне нужно, чтобы отделить его.

"Если бы они знали ;; вы хотели его, entertainment.would есть"

Вот как первая линия должны быть разделены:

Если

них

имеет

известный

вы

пожелал

это

развлечения

бы

имеют

текст будет содержать в самом крайнем случае все стандартные знаки препинания, но и такие вещи, как эллипсы ... двойных черточек -- и т.д.

Как всегда, заранее спасибо.

EDIT:

Таким образом, используя второй stringstream будет выглядеть примерно так?

while(getline(inFile, line)) { 
    istringstream iss(line); 

    while (iss >> word) { 
     istringstream iss2(word); 

     while(iss2 >> letter) { 
      if(!isalpha(letter)) 
       // do something? 
     } 
     // do something else? 
     table1.addItem(word); 
    } 
} 
+0

Используйте поток, чтобы извлечь одно слово, игнорируя пробел (по умолчанию). Затем добавьте новый stringstream и выберете 1 символ за раз, используя 'std :: isalnum', чтобы проверить, должен ли храниться символ. Или используйте 'remove_if' в строке. –

+0

@Neil Kirk Оригинальный пост Отредактировано. Как я могу отбросить/повторно сохранить каждого персонажа, как только я определил, если это письмо или нет? – user3776749

+0

Не добавляйте его в выходную строку, если это не alnum. Письмо должно быть char –

ответ

2

Я не проверял это, так как я не имею г ++ компилятор передо мной сейчас, но он должен работать (за исключением незначительных C++ синтаксических ошибок)

while (getline(inFile, line)) 
{ 
    istringstream iss(line); 

    while (iss >> word) 
    { 
     // check that word has only alpha-numeric characters 
     word.erase(std::remove_if(word.begin(), word.end(), 
            [](char& c){return !isalnum(c);}), 
        word.end()); 
     if (word != "") 
      table1.addItem(word); 
    } 
} 
+0

Это похоже на работу, хотя я еще не провел стресс-теста. Я думаю, что это будет более безопасная ставка, поскольку для этого требуется только . У меня есть один вопрос, хотя, не могли бы вы точно объяснить, что здесь происходит: '[] (char & c) {return! Isalnum (c);}' У меня есть приличная идея, и я узнаю различные детали, но У меня нет контекста для размещения именно того, что он делает. – user3776749

+0

@ user3776749 на самом деле это действительно не работает, как будто строка - это что-то вроде «test.; Works», тогда фрагмент удаляет из него '.;' И выплевывает «тестовые работы» одним словом. Вышеупомянутая функция называется лямбда-функцией (C++ 11) и возвращает true, когда символ не является буквенно-цифровым. Я думаю, лучше всего написать свой собственный токенизатор (или использовать Boost), хотя писать собственное не должно быть слишком больно. Для удовольствия я написал себе токенизатор, и это действительно просто: см. Https://github.com/vsoftco/tokenizer/blob/master/src/token.cpp. Это дает вам общее представление. – vsoftco

+0

@ user3776749 Итак, что вам нужно сделать, это прочитать «слово», начать его синтаксический анализ и найти первый символ, который не является буквенно-цифровым, добавить слово, а затем найти первый символ, который IS буквенно-цифровой, и продолжать повторяться до конца ' слово'. – vsoftco

1

Если вы можете использовать Boost, вы можете сделать следующее:

$ cat kk.txt 
If they had known;; you ... wished it, the entertainment.would have 

Вы можете настроить поведение tokenizer, если это необходимо, но по умолчанию должно быть достаточно.

#include <iostream> 
#include <fstream> 
#include <string> 

#include <boost/tokenizer.hpp> 

int main() 
{ 
    std::ifstream is("./kk.txt"); 
    std::string line; 

    while (std::getline(is, line)) { 
    boost::tokenizer<> tokens(line); 

    for (const auto& word : tokens) 
     std::cout << word << '\n'; 
    } 

    return 0; 
} 

И наконец

$ ./a.out 
If 
they 
had 
known 
you 
wished 
it 
the 
entertainment 
would 
have 
+0

Это интересное решение, и я сохраню его для будущего использования, но чтобы мой учитель не стал суетиться, я хотел бы придерживаться решений, для которых требуются только основные библиотеки функций. – user3776749

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